DEV Community

Maximiliano Burgos
Maximiliano Burgos

Posted on

Curso Kotlin | #8. Null Safety

Bienvenido/a a otro capítulo del Curso de Kotlin! Podés consultar el curso completo desde este link que te dejo acá. Podés seguirme por LinkedIn o Twitter si querés estar al tanto de las próximas publicaciones.

Null Pointer Exception, una vieja historia

Para los recién llegados, existió una antigua era en el mundo de sistemas donde usábamos Java y nuestras aplicaciones tendían a crashear bastante.

El error típico, regado por todo StackOverflow, era el famoso “Null Pointer Exception”.

Se trata de un error donde intentamos llamar a una variable, objeto, método, cualquier cosa que necesite ser instanciada o definida previamente.

Cuando corríamos la aplicación, estallaba. A veces el error era sencillo: nos habíamos olvidado de instanciarla mas arriba. Pero otras, era increíblemente complejo: venía de una lista que se volvía nula en algun momento en tiempo de ejecución, o por algun bug extraño se rompía algún componente.

En esas épocas podías evitar este error a medida que mejorabas como desarrollador, porque parte de tu trabajo se basaba en meter condicionales hasta el cansancio (tema que veremos mas adelante) y también capturar todas las posibles excepciones, incluidas las de null.

Recuerdo que una vez trabajé en una empresa donde teníamos un “Crashlytics day”, el cual se basaba en entrar a Fabric (en ese momento, posteriormente lo se integró con Firebase) y resolver uno o dos bugs que reportaban las aplicaciones en producción. Era muy típico meter un condicional que comprobara si un objeto era nulo, y asi resolver el problema.

Fue una época llena de molestias. Proteger el código es parte de programar, pero en ciertos momentos se podía volver una tarea repetitiva y no gratificante.

Null Safety, el final de la tormenta

Cuando apenas salió Kotlin a la luz para Android, uno de sus principales features anunciados fue una cosa llamada “Null Safety”.

Los que veníamos con Java no comprendíamos que estaba ocurriendo: la gente de Kotlin tenían linternas y nosotros ahí, con nuestra fogata, quemándonos a ratos.

En su conferencia, nos contaron que resolvieron el problema del Null Pointer: habían inventado una forma mas sofisticada de tratar con este problema, cambiando la forma que teníamos de ver a los valores nulos.

Nullable Strings

En la clase anterior creamos un input console del nombre y lo imprimimos:

print("Como es tu nombre? > ")
val name = readLine()
println("Tu nombre es $name")
Enter fullscreen mode Exit fullscreen mode

Pero no nos percatamos de que pasaría si intentamos declarar el tipo de name. Sabemos que devuelve un String:

readLine error

Acto seguido, recibimos un error: Los tipos no coinciden. Esto ocurre porque readLine no nos devuelve un String, sino un Nullable String.

Eso significa que nuestro tipo String podría ser nulo o tener un valor. El signo “?” indica esto, por lo cual vamos a modificarlo:

val name: String? = readLine()
Enter fullscreen mode Exit fullscreen mode

No notamos diferencias con el método println porque si name fuera nula, imprimiría un null sin romperse. Es una de las ventajas del null safety.

No obstante, si queremos llamar a un método de String, la cosa cambia: Transformemos el texto a mayúsculas:

val nameUpper: String? = name?.toUpperCase()
println("Tu nombre es $nameUpper")
Enter fullscreen mode Exit fullscreen mode

Como name es un Nullable String, necesitamos usar el “?” luego de su llamada. Es importante notar que si manejamos nullables, vamos a recibir casi siempre nullables. Por lo cual, nameUpper también lo es.

Esto es el equivalente a lo siguiente:

if(name != null) {
    val nameUpper = name.toUpperCase()
    println("Tu nombre es $nameUpper")
}
Enter fullscreen mode Exit fullscreen mode

Como podemos observar, si condicionamos name, ya no hace falta usar el “?” dentro. Pero esto sería generar código innecesario, porque los nullables ya hacen esto implícitamente por nosotros.

Otro tema interesante es que si declaramos una variable nullable, podemos inicializarla en null:

var name: String? = null
println("Tu nombre es $name")
#output: Tu nombre es null
Enter fullscreen mode Exit fullscreen mode

En este caso es importante declararla como “var” y no “val”, porque en el futuro necesitamos modificar su valor. Sino siempre sería null y perdería su propósito.

Esto va a ser muy útil cuando trabajemos con elementos de vista en Android, los cuales queramos reasignar en algun momento del ciclo de vida de una aplicación.

Encadenar Nullables

Este tema lo mencionamos al pasar en la clase anterior, por lo que ahora con un panorama mas amplio de los nullables, vale la pena repetirlo:

val name = readLine()?.filter { it.isDigit().not() }?.toLowerCase()
Enter fullscreen mode Exit fullscreen mode

En este ejemplo leemos la información en consola, quitamos los dígitos y convertimos el String a minúsculas. Como podemos observar, hay varios “?” en cada método porque algunos de estos valores pueden ser nullables.

Por ejemplo, si introducimos solo numeros, nuestro filtro no encontraría nada, por lo cual sin “?”, nuestro método “toLowerCase” nos arrojaría una excepción.

Podemos encadenar todos los nullables que quisíeramos, siempre y cuando se mantenga una coherencia y las lineas no superen el ancho establecido, y siga siendo legible.

Forzar el Null

En algunos casos muy particulares, quizá no queramos trabajar con los nullables. Supongamos que estamos totalmente seguros de que nuestro String nunca va a ser nulo.

Para asegurar esto, usamos bang bang operator o “!!” de la siguiente manera:

val name: String = readLine()!!
println("Tu nombre es $name")
Enter fullscreen mode Exit fullscreen mode

Pero también podemos mantener la variable como nullable, y en el momento de usar algún método, forzarlo:

val name: String? = readLine()
println("Tu nombre es ${name!!.toUpperCase()}")
Enter fullscreen mode Exit fullscreen mode

Es importante aclarar que forzar nullables rompe con las buenas prácticas que trae Kotlin a la mesa. Solo debemos usarlo en caso de no tener otra alternativa. Por ejemplo, si abusamos del “!!” y se llama a un método de un objeto nulo, la aplicación va a crashear tal como pasaba en Java.

Conclusiones

Null Safety es un tema algo complejo de entender al inicio, pero cuando lo llevamos a la práctica se vuelve muy sencillo. Recomiendo practicar esto no solo con Strings, sino también con los otros tipos de datos como Int o Boolean, por ejemplo.

¡Los espero en la siguiente clase!

Top comments (0)