Seguridad contra nulos: Tipos no nulos y nulabilidad en Kotlin
Índice de contenido
Uno de los problemas que tenemos al momento de desarrollar aplicaciones en muchos de los lenguajes de programación hoy en día como C#, Java y nuestro caso de interés que es desarrollar aplicaciones con Android, es el más que molesto NULLPointerException de Java o la Excepción a referencias nulas que puede aparecer en nuestra aplicación cuando menos nos lo esperamos; Kotlin ofrece varios métodos muy interesantes para lidiar con esto molesto escenario y con muy poco código y de una manera muy fácil.
Anteriormente vimos como emplear variables, tipos de datos, mutables e inmutables y Operadores en Kotlin
️ Seguridad contra tipos nulos (Null Safety)
La seguridad contra tipos nulos, o la protección contra los famosos NullPointerException, es una pieza fundamental en cualquier lenguaje de programación moderno de alto nivel, como Kotlin.
Uno de los errores más comunes al programar es que salte un "bendito nulo". Por ejemplo, en lenguajes de bajo nivel como C, prácticamente todo puede derivar en un error de este tipo. Para evitar estos problemas, Kotlin integra la nulabilidad directamente en su sistema de tipos.
En esta entrada veremos cómo manejar los tipos de datos no nulos (que no se les permite ser nulos), los que pueden ser nulos y cómo manejar en lo que sería en Java una excepción de tipo NULLPointerException en Kotlin.
Tipos no nulos (Non-NULLable types)
Por defecto, los tipos de datos en Kotlin no se les permite ser nulos, que de por sí sería una buena idea ya que el compilador nos avisará si en algún momento establecemos de manera programática (en el código) dicha variables como nulo:
var a: String = "abc"Si intentamos referenciar un valor nulo
var a: String = "abc"
a = null // error de compiladorEl compilador nos daría un error; el problema viene ahora si el valor viene de alguna otra fuente como datos de entrada o de un servidor provista de una consulta (en resumen, en tiempo de ejecución), etc que nos pueda dar un valor nulo para esta variable, para estos casos y cuando queremos que nuestra variable pueda ser nula debemos hacer lo explicado en la siguiente sección.
Declaración de variables y el uso de ?
Si intentas asignar null a una variable normal, el compilador lanzará una excepción indicando que no está permitido. Sin embargo, muchas veces necesitamos que una variable pueda ser nula (por ejemplo, al recibir datos de una API). Para ello, añadimos un signo de interrogación después del tipo de dato:
var a: String? = "abc"
a = null // el compilador lo permitePor supuesto, con esto volvemos al problema inicial con las referencias nulas en las propiedades y métodos que podamos emplear en nuestras variables definidas y con esto el problema inicial en un ciclo que no parece tener fin.. o no.
El compilador de Kotlin nos obliga a comprobar si una variable es definida como NULLable o que pueda ser nula antes de emplear una propiedad o método de la misma; es decir, si tenemos el siguiente fragmento de código:
val x: Int? = nullE intentado emplear algún método o propiedad:
val h = x.toDouble()No compilaría hasta que comprobemos si no es nula:
if (x != null) {
val h = x.toDouble()
}️ Operadores de protección
Cuando trabajamos con variables que pueden ser nulas, Kotlin nos obliga a ser cuidadosos al llamar a sus métodos o propiedades. Aquí entran en juego tres operadores clave.
1. Safe Call Operator (?.)
Si queremos poder emplear las propiedades y métodos provistos por la API de Kotlin o generados por terceros o nosotros sin tener miedo de que nos de una excepción a una referencia nula en algún momento podemos emplear el carácter ? delante del nombre de la propiedad método:
var a: String? = "abc"
a = null // bien
a?.length // NULLEn el fragmento de código anterior, si lo ejecutamos al momento de a?.length cuyo valor de la variable a es nulo, nos da que a?.length es nulo también, cosa que no sucedería si no empleamos el carácter ? delante del nombre de la propiedad a acceder (?.length).
Otro ejemplo:
val x: Int? = null
println(x?.toDouble()) // Imprime "null" en lugar de romperse2. Not-Null Assertion Operator (!!)
Existe otro operador que podamos emplear similar al de ? empleado anteriormente, y es el operador !! que al ser nulo la variable consultada nos devolvería una excepción:
var a: String? = "abc"
a = null // bien
a!!.length // NULLPointerExceptionEn resumen, el operador ? nos devolvería nulo al momento de acceder a alguna propiedad o método si la variable si es nula, y el operador !! nos devolvería una excepción si se accede a alguna propiedad o método de la variable si es nula.
Este operador se usa cuando estamos completamente seguros de que la variable no es nula. Es el enfoque clásico: si te equivocas y la variable es nula, el programa explotará con una excepción. Úsalo con precaución.
3. Elvis Operator (?:): Retornando valores personalizados en variable nulas
Si queremos que nos retorne otro valor que no sea nulo si no algún otro definido por nosotros también podemos hacer lo siguiente cuyo esquema se parece bastante a los condicionales cortos en PHP (El Operador Elvis):
val x: Int? = null
val resultado = x ?: 80
println(resultado) // Imprime 80
val l = b?.length ?: -1Su función es asignar un valor por defecto en caso de que la referencia sea nula. Es el punto medio ideal: no explota la aplicación, pero tampoco te deja un nulo vacío.
Conclusión
El concepto es el mismo ya sea para un String, un Int o cualquier objeto complejo. Si tienes una variable que podría ser nula, protégete usando estos operadores. Si no quieres que tu aplicación "te explote en la cara" con una excepción o que simplemente muestre un nulo, el Elvis Operator es tu mejor aliado.
Ya con esto podemos emplear los tipos de datos en Kotlin sin problemas, si queremos emplear el nuevo esquema de Kotlin que no permite nulos por defectos, o el más común que permite nulos pero con el problema de las referencias nulas, ya sabemos como tratar para evitar las referencias nulas al momento de acceder a las propiedades o métodos; en la siguiente entrada veremos cómo emplear los métodos y clases en Kotlin.
El siguiente paso, aprende a usar los condicionales en Kotlin: if y when.
Acepto recibir anuncios de interes sobre este Blog.
Hablaremos sobre los tipos de datos nulos y no nulos además de los operadores unarios para los tipos de datos nulos que permiten acceder a las propiedades de las variables de manera segura incluso cuando la referencia es nula en Kotlin.