Перейти к основному содержимому
Версия: Legacy

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-значения можно использовать не только в переменных, но и в параметрах и возвращаемом типе функции.

Пример: 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: обработка чисел

Сумма двух nullable-чисел
val a: Int? = 10
val b: Int? = 5

val sum = (a ?: 0) + (b ?: 0) // Если a или b = null, считаем их как 0
println("Сумма: $sum")
В консоли
Сумма: 15



Пример 2: работа со списками

Поиск элемента в nullable-списке
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 на дефолтное значение.