Reified en Kotlin: la magia de los genéricos para principiantes

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

¿Qué es reified en Kotlin y por qué es «magia»?

\n

Si alguna vez has programado en Java, seguramente te has topado con Type Erasure — la eliminación de tipos en tiempo de ejecución. En Java (y en Kotlin por defecto) la información sobre el tipo dentro de los genéricos solo está disponible en la etapa de compilación, y en tiempo de ejecución desaparece. Esto significa que no puedes escribir if (value is T) o T::class dentro de una función normal, porque T en tiempo de ejecución es simplemente Object.

\n

Pero Kotlin fue más allá. La palabra clave reified (del inglés «reificado») permite «revivir» el tipo dentro de una función inline. Gracias a reified puedes hacer lo que en Java parecía imposible: verificar el tipo, obtener KClass, crear instancias e incluso trabajar con reflexión — todo en tiempo de ejecución.

\n

En este artículo analizaremos cómo funciona reified, con ejemplos reales que podrás aplicar de inmediato. ¡Vamos allá!

\n\n

El problema: Type Erasure en acción

\n

Imagina: estás escribiendo una función que debe verificar si un objeto es una cadena. Un intento ingenuo:

\n
fun <T> isString(value: Any): Boolean {\n    return value is T // ¡Error de compilación!\n}
\n

El compilador mostrará un error: "Cannot check for instance of erased type: T". ¿Por qué? Porque en tiempo de ejecución la JVM no sabe qué es T. Para ella, T es simplemente Object.

\n

Lo mismo ocurre al obtener la clase: T::class dentro de una función normal tampoco funcionará. Esto es Type Erasure — el principal dolor de cabeza de los desarrolladores de Java.

\n\n

Solución: reified + inline

\n

Kotlin ofrece una solución elegante. Para «recordar» el tipo en tiempo de ejecución, debes hacer la función inline y marcar el parámetro de tipo con la palabra clave reified:

\n
inline fun <reified T> isString(value: Any): Boolean {\n    return value is T // ¡Ahora funciona!\n}
\n

Ahora puedes llamarla:

\n
println(isString<String>("Hola")) // true\nprintln(isString<Int>("Hola"))    // false
\n

¿Cómo funciona? Cuando marcas una función como inline, el compilador inserta su código directamente en el lugar de la llamada. Y reified hace que el compilador sustituya el tipo concreto (por ejemplo, String) en lugar de T en el código generado. Como resultado, en el bytecode aparece una verificación explícita value is String.

\n\n

Ejemplos prácticos de uso de reified

\n

Veamos algunos escenarios reales donde reified realmente simplifica la vida.

\n\n

1. Obtener la clase en tiempo de ejecución

\n

Una de las tareas más comunes es obtener KClass o Class a partir del parámetro de tipo. Sin reified es imposible:

\n
inline fun <reified T> getKClass(): KClass<T> = T::class\n\n// Uso:\nval kClass = getKClass<String>()\nprintln(kClass.simpleName) // String
\n

Esto es especialmente útil al trabajar con librerías que requieren reflexión (por ejemplo, serialización, ORM, contenedores DI).

\n\n

2. Crear una instancia según el tipo

\n

¿Quieres crear un objeto del tipo deseado sin pasar un constructor? Fácil:

\n
inline fun <reified T : Any> createInstance(): T {\n    return T::class.createInstance()\n}\n\n// Ejemplo:\nval instance = createInstance<StringBuilder>()\ninstance.append("¡Hola, reified!")
\n

Pero ten cuidado: createInstance() solo funciona si la clase tiene un constructor sin parámetros. De lo contrario, obtendrás una excepción.

\n\n

3. Filtrar por tipo en colecciones

\n

Supongamos que tienes una lista de objetos de diferentes tipos y quieres filtrar solo las cadenas. En la biblioteca estándar de Kotlin existe filterIsInstance<T>(), pero puedes escribir fácilmente tu propia versión:

\n


                
                

Blogs

Book Recommendations