Smart cast en Kotlin: por qué una variable podría cambiar y cómo solucionarlo en 2025

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

«¡Pero si acabo de comprobarlo!» — el dolor familiar de todo desarrollador Kotlin

\n

Estás escribiendo en Kotlin, disfrutando de su concisión y seguridad, cuando de repente — una línea ondulada roja. El compilador muestra: Smart cast to 'Type' is impossible, because 'variable' is a mutable property that could have been changed by this time. ¿Te suena? Si alguna vez te has encontrado con este error, no estás solo. Esta pregunta es una de las más populares en Stack Overflow, y con razón: plantea un tema fundamental: cómo Kotlin nos protege de nosotros mismos.

\n

En este artículo no solo analizaremos por qué ocurre el error, sino que también mostraremos cómo evitarlo elegantemente en 2025. Aprenderás qué es el smart cast (conversión inteligente), por qué Kotlin no confía en las propiedades mutables, y cuáles son las mejores prácticas que te ayudarán a escribir código limpio y seguro sin «parches» innecesarios. ¡Allá vamos!

\n\n

¿Qué es el smart cast y por qué es «inteligente»?

\n

Una de las grandes fortalezas de Kotlin es la conversión inteligente de tipos. Esto ocurre cuando el compilador entiende por sí mismo que, después de verificar el tipo de una variable, se puede usar como ese tipo, sin necesidad de una conversión explícita. Por ejemplo:

\n
fun printLength(obj: Any) {\n    if (obj is String) {\n        // Smart cast: obj automáticamente se convierte en String\n        println(obj.length)\n    }\n}
\n

Bonito, ¿verdad? El compilador ve: «Ajá, hemos comprobado que obj es un String, entonces dentro del bloque if es definitivamente una cadena, se puede llamar a length». Esto es el smart cast.

\n

Pero hay un detalle: este truco solo funciona si el compilador puede garantizar que la variable no cambiará entre la comprobación y el uso. Pero si la variable es var (mutable), no hay garantías. Y aquí empieza la diversión.

\n\n

La raíz del problema: mutable property (propiedad mutable)

\n

Veamos un ejemplo típico que provoca el error:

\n
class UserRepository {\n    var currentUser: User? = null\n\n    fun printUserName() {\n        if (currentUser != null) {\n            // ¡Error! Smart cast to 'User' is impossible\n            // porque currentUser es var y podría haber cambiado\n            println(currentUser.name)\n        }\n    }\n}
\n

¿Cuál es el problema? ¡Acabamos de comprobar que currentUser no es null! El compilador responde: «Amigo, estás usando var. Esto significa que entre la comprobación y la llamada a println, otro hilo (o incluso este mismo código en otro lugar) podría haber cambiado currentUser de vuelta a null. No puedo arriesgarme — ¿y si ocurre un NPE?».

\n

¡Y esto es correcto! Kotlin es un lenguaje con filosofía null-safe. No te permite dispararte en el pie. Incluso si estás seguro de que nadie cambiará la propiedad, el compilador se cubre las espaldas. Esto es mejor que tener que lidiar con un NullPointerException en tiempo de ejecución.

\n\n

¿Cómo solucionarlo? 5 formas probadas (edición 2025)

\n

La buena noticia: hay varias soluciones, y todas son sencillas. Elige la que mejor se adapte a tu estilo de código y a la situación.

\n\n

1. Copia local inmutable (la más fiable)

\n

La forma más directa es guardar el valor en un val (variable local inmutable). El compilador ve inmediatamente que el val local no será modificado por nadie, y el smart cast funciona:

\n
fun printUserName() {\n    val user = currentUser\n    if (user != null) {\n        // ¡Smart cast funciona! user es un val local\n        println(user.name)\n    }\n}
\n

Este truco es el estándar de oro. Es simple, legible y no requiere bibliotecas adicionales. En 2025 sigue siendo la forma más recomendada.

\n\n

2. Función let (una forma elegante)

\n

La función let es una excelente herramienta para trabajar con valores nullable. Ejecuta un bloque de código solo si el objeto no es null, y dentro del bloque el objeto está disponible como it (o se le puede asignar un nombre):

Blogs

Book Recommendations