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 de lectura • Equip Q2BSTUDIO

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.

UNA PAUSA?

Juga una estona abans de marxar

ELS NOSTRES SERVEIS

Com et podem ajudar

Intel·ligència artificial

Agents d'IA, chatbots i assistents intel·ligents que automatitzen tasques i atenen els teus clients 24/7 per millorar l'eficiència del teu negoci.

Més info

Desenvolupament de programari

Aplicacions web, mòbils i d'escriptori, intranets, e-commerce, SaaS i plataformes de gestió dissenyades per a les necessitats concretes de la teva empresa.

Més info

Serveis cloud

Migració, infraestructura, hosting gestionat, alta disponibilitat i seguretat en Microsoft Azure i Amazon Web Services perquè el teu negoci escali sense límits.

Més info

Ciberseguretat i pentesting

Auditories de seguretat, test d'intrusió (pentesting) i protecció d'aplicacions, dades i infraestructura on-premise i cloud, amb hacking ètic i compliment normatiu.

Més info

Business Intelligence

Quadres de comandament i anàlisi de dades amb Power BI: integrem les teves fonts, dissenyem dashboards i KPIs i convertim les teves dades en decisions.

Més info

Automatització de processos

Automatitzem tasques repetitives i connectem les teves aplicacions amb n8n, Power Automate, Make i RPA, eliminant treball manual i augmentant la productivitat.

Més info

Formació per a empreses

Formem els teus equips en tecnologia amb criteri: desenvolupament web, bases de dades, Git, bones pràctiques i seguretat, automatització amb n8n, intel·ligència artificial per a empreses i creació de solucions d'IA amb Azure AI Foundry.

Més info

Auditoria de codi

Auditem el codi que creguis tu, el teu equip o una IA: et diem què està bé i què millorar, el securitzem i el deixem llest per a producció, web o app.

Més info

Generació d'imatges amb IA

Creem per tu les imatges que necessita el teu negoci amb intel·ligència artificial: producte, xarxes, publicitat, il·lustració i avatars. Tu ens dius què vols i t'ho lliurem llest per fer servir.

Més info

Generació de vídeos amb IA

Creem per tu vídeos amb intel·ligència artificial: promocionals, per a xarxes, presentadors virtuals, doblatge i animacions. Ens comptes la idea i t'ho lliurem muntat i llest per publicar.

Més info

Avatars conversacionals amb IA

Creem avatars conversacionals amb IA —humans digitals amb cara i veu— que atenen els teus clients i equips amb el coneixement de la teva empresa, a la teva web, monitors interactius, WhatsApp o Teams.

Més info

Màrqueting Online i IA

Google Ads, Meta Ads, LinkedIn Ads i posicionament en motors d'IA (GEO/AEO): captem clients i fem que la teva marca aparegui on et busquen, també a ChatGPT, Gemini i Perplexity.

Més info

Tens un projecte en ment?

Explica'ns la teva visió i la convertim en una solució de programari. Sigui quin sigui l'abast, fem realitat la teva idea.

Live Chat