← Kotlin EspañolChapter 06 of 13

Seguridad Nula

## Objetivos de Aprendizaje - Comprender el sistema de seguridad nula de Kotlin - Usar el operador de llamada segura (?.) - Trabajar con el operador Elvis (?:) - Usar la aserción no-nula (!!) - Aprender sobre casts seguros (as?) ## Tipos Anulables El sistema de tipos de Kotlin distingue entre tipos anulables y no anulables: ```kotlin fun main() { // Non-nullable - cannot hold null val name: String = "Kotlin" // name = null // Error! // Nullable - can hold null var nullableName: String? = "Kotlin" nullableName = null // OK println(nullableName) } ``` ## Operador de Llamada Segura (?.) El operador de llamada segura retorna null si el objeto es null: ```kotlin fun main() { val str: String? = "Hello" // Safe call - returns length or null val length1 = str?.length println("Length 1: $length1") // 5 str = null val length2 = str?.length println("Length 2: $length2") // null } ``` ### Encadenando Llamadas Seguras ```kotlin fun main() { val person: Person? = Person(Address("New York")) // Chained safe calls val city = person?.address?.city println("City: $city") // New York (or null if any part is null) person?.address = null val city2 = person?.address?.city println("City 2: $city2") // null } class Person(var address: Address?) class Address(var city: String?) ``` ## Operador Elvis (?:) El operador Elvis proporciona un valor por defecto cuando es null: ```kotlin fun main() { val str: String? = null // Without Elvis - returns null val length1 = str?.length println("Length: $length1") // null // With Elvis - returns default val length2 = str?.length ?: 0 println("Length: $length2") // 0 } ``` ### Elvis con throw ```kotlin fun main() { val str: String? = null // Elvis can throw exceptions too val nonNull = str ?: throw IllegalArgumentException("String cannot be null") } fun getName(person: Person?): String { return person?.name ?: "Unknown" } ``` ## Aserción No-Nula (!!) Usa `!!` cuando estás seguro de que un valor no es null: ```kotlin fun main() { val str: String? = "Hello" // !! asserts value is not null val length = str!!.length println("Length: $length") // 5 // If null, throws NullPointerException val nullStr: String? = null // nullStr!!.length // Throws NullPointerException } ``` ### Cuándo Usarlo - Solo cuando estás absolutamente seguro de que el valor no es null - Evita usar `!!` en código de producción - Elimina el propósito de la seguridad nula de Kotlin ## Cast Seguro (as?) El cast seguro retorna null en lugar de lanzar ClassCastException: ```kotlin fun main() { val obj: Any = "Hello" // Regular cast - throws if fails // val str: String = obj as String // Safe cast - returns null if fails val str: String? = obj as? String println("Safe cast: $str") // Hello val num: Int? = obj as? Int println("Safe cast to Int: $num") // null } ``` ## Función Let Usa `let` para ejecutar código solo si el valor no es null: ```kotlin fun main() { val str: String? = "Hello" // execute only if not null str?.let { println("Length: ${it.length}") } // with default behavior str?.let { it.length } ?: println("String is null") } ``` ### Let con Múltiples Verificaciones de Null ```kotlin fun main() { val firstName: String? = "John" val lastName: String? = "Doe" // Combining multiple lets firstName?.let { f -> lastName?.let { l -> println("$f $l") } } } ``` ## Resumen del Operador ? | Operador | Descripción | Retorna | |----------|-------------|---------| | `?.` | Llamada segura | `null` si el receptor es `null` | | `?:` | Operador Elvis | Valor por defecto si izquierda es `null` | | `!!` | Aserción no-nula | Lanza NPE si es `null` | | `as?` | Cast seguro | `null` si el cast falla | ## Seguridad Nula con Colecciones ```kotlin fun main() { val list: List? = listOf("a", "b", "c") // Safe call with size println(list?.size) // 3 list = null // Empty list if null val size = list?.size ?: 0 println(size) // 0 // Null list val emptyList = list?.filter { it.isNotEmpty() } ?: emptyList() println(emptyList) // [] } ``` ## Tipos de Plataforma Cuando se usa código Java desde Kotlin, los tipos de Java pueden ser tipos de plataforma (pueden ser null o no nulos): ```kotlin // Java code public class JavaExample { public String getGreeting() { return "Hello"; } } ``` ```kotlin // Kotlin code calling Java fun main() { val javaExample = JavaExample() val greeting: String = javaExample.getGreeting() // Non-null // If Java method returns @Nullable String // Then Kotlin sees it as String? } ``` ## Verificando Null en Condiciones ```kotlin fun main() { val str: String? = "Hello" // Regular null check if (str != null) { println(str.length) // Smart cast to String } // After null check, smart cast applies // Works only with local variables } ``` ### Nota sobre Casts Inteligentes Los casts inteligentes no funcionan con variables mutables o propiedades que podrían ser cambiadas: ```kotlin fun main() { var str: String? = "Hello" // Smart cast doesn't work because var can be changed // str could be changed to null between check and use if (str != null) { // println(str.length) // Error: only safe call allowed } // Safe call works println(str?.length) } ``` ## Resumen - Kotlin distingue tipos anulables (`T?`) y no anulables (`T`) - `?.` la llamada segura retorna null si el receptor es null - `?:` el operador Elvis proporciona valor por defecto - `!!` afirma no-null, lanza NPE si está mal - `as?` cast seguro retorna null en caso de fallo - `?.let { }` ejecuta bloque solo si no es null - Prefiere llamadas seguras sobre `!!` en código de producción - Los casts inteligentes funcionan con variables locales inmutables

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →