Kotlin: Preguntas sobre Genéricos

Descubre conceptos clave y respuestas prácticas sobre genéricos en Kotlin: varianza, reified y proyecciones de tipo, con ejemplos y preguntas.

20 ago 2025 • 6 min read • Q2BSTUDIO Team

Inteligencia-Artificial-

En este articulo revisamos conceptos clave y preguntas practicas sobre genericos en Kotlin, traducido y adaptado al español para facilitar su comprension.

Los genericos en Kotlin permiten escribir clases, interfaces y funciones con un marcador de tipo para crear codigo reutilizable y seguro en tiempo de compilacion que funciona con diferentes tipos.

Existen dos enfoques para la varianza: declaration-site variance en la propia declaracion de la clase o interfaz y use-site variance mediante proyecciones de tipo en las firmas de funciones.

Palabras clave fundamentales

out indica que el tipo es un productor y puede devolver valores del tipo T.

in indica que el tipo es un consumidor y puede aceptar valores del tipo T.

where permite definir varias restricciones sobre un parametro generico.

reified conserva informacion de tipo en tiempo de ejecucion en funciones inline, permitiendo comprobaciones seguras con is y conversiones con as.

Any? es el supertipo de todos los tipos. Nothing es el subtipo final de todos los tipos.

Ejemplo de interfaz productora: interface Source<out T> { fun nextT(): T }

Covarianza: declarada con out, permite que una clase parametrizada sea considerada productora del tipo. Es equivalente a Java C<? extends Base> y un ejemplo comun es List.

Contravarianza: declarada con in, convierte el parametro en consumidor. Un ejemplo tipico es Comparable con la firma interface Comparable<in T> { operator fun compareTo(other: T): Int }

Invarianza: algunas clases aceptan y producen el mismo tipo, por eso no pueden ser ni co ni contravariantes. Un ejemplo es Array.

Type erasure: en tiempo de ejecucion las instancias genericas no retienen informacion del parametro T para asegurar interoperabilidad con JVM antiguas.

Star projections resuelven la seguridad de tipo cuando se desconoce el argumento generico. Para una interfaz Function<in T, out U>:

Function<*, String> equivale a Function<in Nothing, String>.

Function<Int, *> equivale a Function<Int, out Any?>.

Function<*, *> equivale a Function<in Nothing, out Any?>.

Para declarar que un T generico no puede ser nulo se usa T & Any. El caracter guion bajo puede utilizarse para que el compilador infiera automaticamente un argumento de tipo cuando otros estan especificados.

Preguntas y respuestas practicas

Pregunta 1: Por que no esta permitido hacer esto: class Box<T>(val value: T) fun takeBox(box: Box<Any>) { println(box.value) } fun main() { val strBox = Box('Hello') takeBox(strBox) }

Respuesta: Los genericos son invariante por defecto. Aunque Int es subtipo de Any, Box<Int> no es subtipo de Box<Any>, por eso la llamada no compila.

Pregunta 2: Cual seria la salida del codigo fun <T> isString(value: T): Boolean { return value is String } fun main() { println(isString('Hello')) println(isString(42)) }

Respuesta: Imprimira true y luego false. Aunque T esta sujeto a type erasure, la comprobacion is se aplica sobre el valor concreto en tiempo de ejecucion.

Pregunta 3: Que significa esto: fun <T> onlyNumbers(a: T, b: T): T where T : Number, T : Comparable<T> { return if (a > b) a else b }

Respuesta: T debe ser un Number y ademas implementar Comparable de si mismo. where se utiliza para indicar multiples restricciones sobre T.

Pregunta 4: Por que no compila este ejemplo: fun copy(first: Array<out Any>, second: Array<Any>) { for (i in first.indices) { first[i] = second[i] } } fun main() { val strings = arrayOf('A', 'B', 'C') val anys = Array<Any>(3) { '' } copy(strings, anys) }

Respuesta: El parametro first esta declarado con out y por tanto es un productor solo, no puede aceptar valores via asignacion first[i] = ...

Pregunta 5: Compilara esto: class Box<T>(val value: T) { fun <T> printTwice(t: T) { println('$value $t') } } fun main() { val box = Box('Kotlin') box.printTwice(42) }

Respuesta: Si compila. El parametro generico de la funcion printTwice sombreado resulta en un nuevo T local a la funcion. Imprimira Kotlin 42.

Pregunta 6: Compilara este bloque: fun fill(list: MutableList<out Number>) { list.add(42) }

Respuesta: No compila. MutableList<out Number> es productor y por tanto no puede recibir elementos mediante add.

Pregunta 7: Por que esto no funciona: fun mystery(list: MutableList<*>) { list.add(null) }

Respuesta: MutableList<*> es una proyeccion estrella que equivale a MutableList<out Any?>, es tratada como productora y no admite insercion de elementos no nulos. Solo se permite añadir null si la lista lo admite y la firma lo permite, pero en general la proyeccion impide add.

Pregunta 8: Por que no esta permitido esto: fun <T : Number> sum(a: T, b: T): T { return a + b }

Respuesta: El operador plus no esta definido en la clase Number, sino en subtipos concretos como Int o Double. Para sumar genericos de Number es necesario convertir o trabajar con operaciones definidas en subtipos o proporcionar una estrategia de suma.

Pregunta 9: Cual sera la salida de este codigo con reified: inline fun <reified T> check(value: Any) { println(value is T) } fun main() { check<List<String>>(listOf('a', 'b')) check<List<Int>>(listOf('a', 'b')) }

Respuesta: Imprimira true y true. reified conserva la informacion del tipo top level List, pero no evita el type erasure de los parametros internos, asi que ambas comprobaciones ven solo que value es una List.

Pregunta 10: Por que no se permite esto: object Cache<T> { private val items = mutableListOf<T>() }

Respuesta: object define un singleton con una unica instancia; un singleton no puede ser parametrizado con tipos distintos en tiempo de ejecucion, por eso no se permiten genericos en object.

Pregunta 11: Para que sirve esta declaracion: interface ComparableSelf<T : ComparableSelf<T>> { fun compareTo(other: T): Int }

Respuesta: Obliga a que las clases que implementen la interfaz declaren compareTo que reciba su propio tipo, garantizando comparabilidad estricta entre instancias del mismo tipo.

Pregunta 12: Es correcta la siguiente declaracion: class Box<T : Int>(val value: T)

Respuesta: No tiene sentido porque Int es final y no puede ser subtipo. En ese caso basta declarar class Box(val value: Int).

Pregunta 13: Cual sera la salida de este ejemplo con sobrecarga de funciones: fun <T> printType(value: T) { println('Generic') } fun printType(value: String) { println('String') } fun main() { printType('Hello') }

Respuesta: Imprimira String. El compilador elige la funcion mas especifica que coincide con los argumentos.

Pregunta 14: Cual sera la salida usando reified para obtener la clase: inline fun <reified T> printClass(list: List<T>) { println(T::class.java) } fun main() { printClass(listOf('A', 'B')) printClass(listOf(1, 2, 3)) }

Respuesta: Mostrara class java.lang.String y class java.lang.Integer. reified preserva el tipo T en tiempo de ejecucion para este proposito.

Si quieres profundizar mas en Kotlin y genericos puedes contactarnos para formacion, auditorias de codigo y migraciones de proyectos.

Sobre Q2BSTUDIO

Q2BSTUDIO es una empresa de desarrollo de software y aplicaciones a medida especializada en soluciones empresariales modernas. Ofrecemos software a medida, aplicaciones a medida, proyectos de inteligencia artificial y servicios de ciberseguridad. Ademas trabajamos con servicios cloud aws y azure para desplegar arquitecturas escalables y seguras.

Nuestros servicios incluyen servicios inteligencia de negocio, implementacion de power bi, ia para empresas, agentes IA y soluciones personalizadas de machine learning. Combinamos experiencia en desarrollo de aplicaciones a medida y software a medida con practicas de ciberseguridad y operaciones en la nube para ofrecer productos listos para produccion.

Si buscas potenciar datos con inteligencia artificial, monitorizar seguridad, migrar a servicios cloud aws y azure o desplegar soluciones con power bi y agentes IA, Q2BSTUDIO puede ayudarte a diseñar e implementar la solucion adecuada.

Palabras clave para posicionamiento: aplicaciones a medida, software a medida, inteligencia artificial, ciberseguridad, servicios cloud aws y azure, servicios inteligencia de negocio, ia para empresas, agentes IA, power bi.

Contacta con Q2BSTUDIO para consultar proyectos de desarrollo de aplicaciones a medida y soluciones de inteligencia artificial que aporten valor real a tu negocio.

A BREAK?

Play for a moment before you go

OUR SERVICES

How we can help you

Artificial intelligence

AI agents, chatbots, and intelligent assistants that automate tasks and serve your customers 24/7 to improve the efficiency of your business.

More info

Software Development

Web, mobile, and desktop applications, intranets, e-commerce, SaaS, and management platforms designed for your company's specific needs.

More info

Cloud services

Migration, infrastructure, managed hosting, high availability, and security on Microsoft Azure and Amazon Web Services to help your business scale without limits.

More info

Cybersecurity and pentesting

Security audits, penetration testing and protection of applications, data and infrastructure on-premise and cloud, with ethical hacking and regulatory compliance.

More info

Business Intelligence

Dashboards and data analysis with Power BI: we integrate your sources, design dashboards and KPIs and turn your data into decisions.

More info

Process automation

We automate repetitive tasks and connect your applications with n8n, Power Automate, Make, and RPA, eliminating manual work and increasing productivity.

More info

Training for Companies

We train your teams in technology with criteria: web development, databases, Git, best practices and security, automation with n8n, artificial intelligence for companies and creation of AI solutions with Azure AI Foundry.

More info

Code Auditing

We audit the code that you, your team or an AI create: we tell you what is good and what to improve, we secure it and make it ready for production, web or app.

More info

AI Image Generation

We create for you the images that your business needs with artificial intelligence: product, networks, advertising, illustration and avatars. You tell us what you want and we deliver it ready to use.

More info

AI Video Generation

We create videos with artificial intelligence for you: promotional, networking, virtual presenters, dubbing and animations. You tell us the idea and we will deliver it assembled and ready to publish.

More info

AI Conversational Avatars

We create conversational avatars with AI – digital humans with a face and voice – that serve your customers and teams with the knowledge of your company, on your website, interactive monitors, WhatsApp or Teams.

More info

Online Marketing and AI

Google Ads, Meta Ads, LinkedIn Ads and AI Engine Positioning (GEO/AEO): we attract customers and make your brand appear where they search for you, also on ChatGPT, Gemini and Perplexity.

More info

Do you have a project in mind?

Tell us your vision and we'll turn it into a software solution. Whatever the scope, we make your idea real.

Live Chat