El sistema de tipos de Kotlin tiene como objetivo eliminar el peligro de la referencia nula del código porque es un error de mil millones de dólares. El programa genera NullPointerExceptions en tiempo de ejecución y, a veces, provoca fallas en la aplicación o bloqueos del sistema.
Si alguien ha estado programando en Java u otro lenguaje que tiene el concepto de referencia nula, entonces debe haber experimentado NullPointerException en el código. El compilador de Kotlin también lanza NullPointerException si encuentra alguna referencia nula sin ejecutar ninguna otra declaración.
Las posibles causas de NullPointerException son las siguientes:
- Llamada explícita para lanzar NullPointerException()
- Uso del !! operador
- Alguna inconsistencia de datos con respecto a la inicialización, por ejemplo, un esto no inicializado se pasa como argumento.
- Interoperaciones de Java, como intentos de acceder a un miembro en una referencia nula, tipo genérico con nulabilidad incorrecta.
Tipos anulables y no anulables en Kotlin –
El sistema de tipos de Kotlin ha distinguido dos tipos de referencias que pueden contener valores nulos (referencias anulables) y aquellas que no pueden (referencias no nulas).
Una variable de tipo String no puede contener nulo . Si tratamos de asignar nulo a la variable, da un error de compilación.
var s1: String = "Geeks" s1 = null // compilation error
Para permitir que una variable se mantenga nula, podemos declarar una variable como una string anulable, escrita String?
var s2: String? = "GeeksforGeeks" s2 = null // ok print(s2)
Ahora, si queremos acceder a la longitud de la string s1, garantiza no arrojar NPE, por lo que podemos decir con seguridad:
val l = s1.length
Pero si queremos acceder a la longitud de la string s2, eso no sería seguro y el compilador reporta un error:
val l = s2.length // error: variable 's2' can be null
Programa Kotlin de tipo no anulable –
Kotlin
fun main(args: Array<String>){ // variable is declared as non-nullable var s1 : String = "Geeks" //s1 = null // gives compiler error print("The length of string s1 is: "+s1.length) }
Producción:
The length of string s1 is: 5
Aquí, si tratamos de asignar un valor nulo a una variable que no admite valores nulos, se produce un error de tiempo del compilador. Pero, si intentamos acceder a la longitud de la string, garantiza que no lo hagamos a través de NullPointerException.
Programa Kotlin de tipo anulable-
Kotlin
fun main(args: Array<String>) { // variable is declared as nullable var s2: String? = "GeeksforGeeks" s2 = null // no compiler error println(s2.length) // compiler error because string can be null }
Producción:
Error:(8, 15) Kotlin: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
Aquí, podemos asignar fácilmente nulo a una variable de tipo anulable. Pero deberíamos usar el operador seguro para obtener la longitud de la string.
Comprobación de nulo en condiciones –
La forma más común de verificar la referencia nula es usar la expresión if-else. Podemos verificar explícitamente si la variable es nula y manejar las dos opciones por separado.
Programa Kotlin de verificación de condiciones nulas –
Kotlin
fun main(args: Array<String>) { // variable declared as nullable var s: String? = "GeeksforGeeks" println(s) if (s != null) { println("String of length ${s.length}") } else { println("Null string") } // assign null s = null println(s) if (s != null) { println("String of length ${s.length}") } else { println("Null String") } }
Producción:
GeeksforGeeks String of length 13 null Null String
Tenga en cuenta que hemos utilizado el bloque if-else para verificar la nulabilidad. Si la string contiene un valor nulo, ejecuta el bloque if; de lo contrario, ejecuta el bloque else.
Operador de llamada segura (?.) –
Las comparaciones nulas son simples, pero la cantidad de expresiones if-else anidadas podría ser una carga. Entonces, Kotlin tiene un operador de llamadas seguras, ?. eso reduce esta complejidad y ejecuta una acción solo cuando la referencia específica tiene un valor no nulo. Nos permite combinar una verificación nula y una llamada de método en una sola expresión.
La siguiente expresión:
firstName?.toUpperCase()
es equivalente a:
if(firstName != null) firstName.toUpperCase() else null
Programa Kotlin de uso de operador seguro –
Kotlin
fun main(args: Array<String>) { // variable declared as nullable var firstName: String? = "Praveen" var lastName: String? = null println(firstName?.toUpperCase()) println(firstName?.length) println(lastName?.toUpperCase()) }
Producción:
PRAVEEN 7 null
Podemos usar el operador de llamada segura con let(), also() y run() si el valor no es nulo
. Método let():
para ejecutar una acción solo cuando una referencia contiene un valor no anulable, podemos usar let operador. La expresión lambda presente dentro de let se ejecuta solo si la variable firstName no es nula.
val firstName: String? = null firstName?.let { println(it.toUpperCase()) }
Aquí, la variable firstName es nula, por lo que la expresión lambda no se ejecuta para convertir la string a letras mayúsculas.
Programa Kotlin de usar let –
Kotlin
fun main(args: Array<String>) { // created a list contains names var stringlist: List<String?> = listOf("Geeks","for", null, "Geeks") // created new list var newlist = listOf<String?>() for (item in stringlist) { // executes only for non-nullable values item?.let { newlist = newlist.plus(it) } } // to print the elements stored in newlist for(items in newlist){ println(items) } }
Producción:
Geeks for Geeks
string de método also() con let() –
Si queremos aplicar alguna operación adicional como imprimir los elementos de la lista que no aceptan valores NULL, podemos usar un método also() y enstringrlo con let() o run() :
Kotlin
fun main(args: Array<String>) { // created a list contains names var stringlist: List<String?> = listOf("Geeks","for", null, "Geeks") // created new list var newlist = listOf<String?>() for (item in stringlist) { // executes only for non-nullable values item?.let { newlist = newlist.plus(it) } item?.also{it -> println(it)} } }
Producción:
Geeks for Geeks
Método run():
Kotlin tiene un método run() para ejecutar alguna operación en una referencia anulable. Parece ser muy similar a let() pero dentro del cuerpo de una función, el método run() opera solo cuando usamos esta referencia en lugar de un parámetro de función:
Kotlin
fun main(args: Array<String>) { // created a list contains names var stringlist: List<String?> = listOf("Geeks","for", null, "Geeks") // created new list var newlist = listOf<String?>() for (item in stringlist) { // executes only for non-nullable values item?.run { newlist = newlist.plus(this) } // this reference item?.also{it -> println(it)} } }
Producción:
Geeks for Geeks
Operador Elvis (?:) –
El operador Elvis se usa para devolver un valor no nulo o un valor predeterminado cuando la variable original es nula. En otras palabras, si la expresión de la izquierda no es nula, el operador elvis la devuelve; de lo contrario, devuelve la expresión de la derecha. La expresión del lado derecho se evalúa solo si el lado izquierdo es nulo.
La siguiente expresión:
val name = firstName ?: "Unknown"
es equivalente a:
val name = if(firstName!= null) firstName else "Unknown"
Además, también podemos usar expresiones throw y return en el lado derecho del operador Elvis y es muy útil en funciones. Por lo tanto, podemos lanzar una excepción en lugar de devolver un valor predeterminado en el lado derecho del operador Elvis.
val name = firstName ?: throw IllegalArgumentException("Enter valid name")
Programa Kotlin de usar el operador Elvis –
Kotlin
fun main(args: Array<String>) { var str : String? = "GeeksforGeeks" println(str?.length) str = null println(str?.length ?: "-1") }
Producción:
13 -1
Afirmación no nula: !! Operador
El operador de aserción no nulo (!!) convierte cualquier valor en un tipo no nulo y genera una excepción si el valor es nulo.
Si alguien quiere NullPointerException, puede preguntar explícitamente usando este operador.
Kotlin
fun main(args: Array<String>) { var str : String? = "GeeksforGeeks" println(str!!.length) str = null str!!.length }
Producción:
13 Exception in thread "main" kotlin.KotlinNullPointerException at FirstappKt.main(firstapp.kt:8)
Publicación traducida automáticamente
Artículo escrito por Praveenruhil y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA