Di adiós a NullPointerException. Trabajando con nulos en Kotlin (KDA 19)

Ya había tardado bastante en dedicarle un artículo a una de las partes más importantes de Kotlin: el tratamiento de nulos.
El propio creador del null reference lo autodenomina como “el error del billón de dólares”, pues es uno de los puntos que más errores genera cuando estás trabajando en este lenguaje.
Si miras a menudo tu gestor de bugs, seguro que el 99% de los errores que ves son NullPointerException
.
Gracias a Kotlin, vas a trabajar en un entorno mucho más seguro (incluso con librerías Java), que reducirá al mínimo estos problemas.
¿Te gustaría comenzar hoy a dar el siguiente paso? Te recomiendo que entres en mi training gratuito aquí
Nulos en Kotlin
Los nulos en Kotlin no existen mientras no se diga lo contrario.
Es decir, a ningún objeto, por defecto, se le puede asignar null
. Recuerda que en Kotlin todos los tipos son objetos.
Por tanto, esto no compilará:
val x: Int = null
Si quieres que una variable acepte nulos, tienes que marcar el tipo con una ?
:
val x: Int? = null
Chequeo en tiempo de compilación
Pero, a partir de ese momento, el compilador te obligará a comprobar el nulo antes de hacer nada con la variable. De esta forma, se asegura de que no se produce un NullPointerException
.
Por ejemplo:
val y = x.toDouble()
No compilará, si no compruebas primero si es nulo:
if (x != null) {
val y = x.toDouble()
}
Expresión de acceso seguro
Existe una expresión mucho más sencilla para representar el ejemplo de antes, que es utilizar una ?
delante del .
cuando se llama a un método.
Si la variable no es nula, ejecutará la operación. En caso contrario, no hará nada:
val y = x?.toDouble()
En este caso, lo que hará si x
es null, es devolver null también. Por lo que y
será de tipo Double?
.
El operador Elvis
¿Pero qué pasa si no queremos tener una variable nullable como resultado de la operación? El operador Elvis (?:
) nos permite devolver un valor en ese caso:
val y = x?.toDouble() ?: 0.0
Este código sería equivalente a:
val y = if (x != null) {
x.toDouble()
} else {
0.0
}
Spoiler: como ves, la mayoría de las sentencias en Kotlin son a su vez expresiones. Por ejemplo, puedes asignar el resultado de un
if
a una variable.
Evitando el chequeo de null
Existe un operador (!!
) que evitará la necesidad de chequear null
si estás completamente seguro de que una variable nunca será nula.
En mi opinión, hay muy pocos casos en los que este operador tiene sentido. Casi siempre hay una solución mejor.
Pero podrías hacer lo siguiente:
val x: Int? = null
val y = x!!.toDouble()
Esto compilaría y produciría una NullPointerException
Lo dicho: mucho cuidado con este operador.
Compatibilidad con Java
Cuando estamos trabajando con librerías Java, podemos encontrarnos ante diferentes situaciones con respecto al chequeo de nulos.
La librería está correctamente anotada
Si se están utilizando adecuadamente las anotaciones @Nullable
y @NotNull
, tanto las de Java como las propias de Android, Kotlin será capaz de trabajar sin problemas con ellas para deducir cuándo una variables es nula y cuándo no.
Muchas partes del framework de Android ya están anotadas correctamente, así que esto es una ventaja enorme para trabajar con Kotlin.
La librería no tiene anotaciones
Sin embargo, si la librería no está anotada, los tipos serán marcados con un operador especial (una única !
), lo que significa que queda en nuestra mano decidir si un parámetro o valor de retorno acepta nulo o no.
Si tenemos acceso al código fuente, lo mejor es comprobar qué valores acepta el código en cuestión que estemos utilizando.
Un ejemplo en Android que no está anotado es la librería de soporte de RecyclerView
. Cuando creas un adapter y autogeneras los métodos, por defecto les añadirá una interrogación a los tipos.
Pero si miras el código fuente, te darás cuenta de que nada puede ser null en los métodos que necesitas sobrescribir. Así que puedes deshacerte de todas las interrogaciones, y evitar chequeos de nulos innecesarios.
Conclusión
Los NullPointerException
son un horror para cualquier desarrollador en Java, y seguramente representen la mayor parte de los errores que se producen en tu código.
Reducir su número en Kotlin hasta casi cero es muy sencillo, incluso cuando se trabajar con librerías y frameworks en Java.
Sólo esto te evitará horas y horas de depuraciones innecesarias, además de que hará el código mucho más estable.
Si te gusta lo que has visto, te animo a que te apuntes al training gratuito, donde te contaré todo lo que necesitas para aprender a crear tus Apps Android en Kotlin desde cero.
Cómo conseguir la localización amplia en Android
Cómo pedir permisos en Jetpack Compose