Null-безопасность в Kotlin
Kotlin предотвращает NullPointerException
на уровне типов. Если переменная может быть null
, это явно указывается в её типе через ?
.
Кроме переменных, nullable-значения можно использовать в параметрах и возвращаемом типе функций.
Объявление nullable-переменных
val name: String? = null // Строка или null
val age: Int? = 25 // Число или null
val list: List<String>? = listOf("A", "B") // Список или null
Проверки на null
1. Явная проверка через if
val text: String? = "Hello"
if (text != null) {
println("Длина текста: ${text.length}") // Безопасный доступ
} else {
println("Текст равен null")
}
Длина текста: 5
Комментарий:
Проверкаtext != null
позволяет использовать переменную как non-null внутри блокаif
.
2. Безопасный вызов (?.
)
val text: String? = null
val length = text?.length // Если text = null, вернет null
println("Длина: ${length ?: "неизвестна"}")
Длина: неизвестна
Комментарий:
text?.length
возвращаетnull
, еслиtext
равенnull
.
?:
задаёт значение по умолчанию.
3. Оператор !!
val text: String? = "Kotlin"
val forcedLength = text!!.length // Уверены, что text != null
println(forcedLength) // 6
// Но если text = null:
// val error = text!!.length // Выбросит NullPointerException
Комментарий:
Используйте!!
только если уверены, что переменная неnull
. В противном случае — крах программы.
Nullable-типы в функциях
Nullable-значения можно использовать не только в переменных, но и в параметрах и возвращаемом типе функции.
fun greet(name: String?): String? {
return if (name != null) "Привет, $name!" else null
}
val message = greet(null) ?: "Имя не указано"
println(message)
Имя не указано
Комментарий:
Функцияgreet
принимаетname: String?
и возвращаетString?
.
Еслиname == null
, функция тоже возвращаетnull
.
Примеры логики
Пример 1: обработка чисел
val a: Int? = 10
val b: Int? = 5
val sum = (a ?: 0) + (b ?: 0) // Если a или b = null, считаем их как 0
println("Сумма: $sum")
Сумма: 15
Пример 2: работа со списками
val list: List<String>? = listOf("Apple", "Banana")
val firstItem = list?.firstOrNull() ?: "Список пуст"
println("Первый элемент: $firstItem")
Первый элемент: Apple
Комментарий:
list?.firstOrNull()
вернетnull
, если списокnull
или пуст.
Оператор?:
заменяетnull
на строку "Список пуст".
Пример 3: цепочка вызовов
data class User(val name: String?, val age: Int?)
val user: User? = User(name = null, age = 30)
val userName = user?.name?.uppercase() ?: "Имя не указано"
println(userName)
Имя не указано
Комментарий:
Еслиuser
,user.name
или любое звено цепочки равноnull
, результат —null
.
Оператор Элвиса заменяет итоговыйnull
на дефолтное значение.