← Назад к вопросам

Что такое null-safety в Kotlin?

1.2 Junior🔥 241 комментариев
#Kotlin основы#Архитектура и паттерны

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое null-safety в Kotlin?

Null-safety — это система типов в Kotlin, которая предотвращает ошибки типа NullPointerException на этапе компиляции, а не во время выполнения. Это одна из главных фишек Kotlin, которая делает код безопаснее и надёжнее. Вместо того чтобы узнавать о null ошибках в продакшене, ты получаешь ошибку компилятора.

Nullable и Non-Nullable типы

В Kotlin каждый тип по умолчанию non-nullable:

// Non-nullable тип (не может быть null)
val name: String = "Android"
// name = null  // ОШИБКА КОМПИЛЯЦИИ!

// Nullable тип (может быть null)
val age: Int? = null  // OK
val city: String? = null  // OK

Вопросительный знак (?) явно указывает, что переменная может содержать null.

Работа с nullable типами

Kotlin предоставляет несколько безопасных способов работы с nullable значениями:

val user: User? = fetchUser()

// 1. Safe call operator (?.)
val userName = user?.name  // userName будет null если user == null
val length = user?.name?.length  // цепочка безопасных вызовов

// 2. Elvis operator (?: )
val displayName = user?.name ?: "Unknown"  // "Unknown" если name null

// 3. Not-null assertion (!!)
val requiredName = user!!.name  // Выбросит исключение если user null

// 4. Let scope function
user?.let {
    println(it.name)  // выполнится только если user не null
    updateUI(it)
}

// 5. If-let (when)
if (user != null) {
    println(user.name)  // Kotlin автоматически кастует к non-null
}

// 6. When expression
when (user) {
    null -> println("No user")
    else -> println(user.name)  // user non-null внутри блока
}

Практический пример на Android

data class UserProfile(
    val id: String,
    val name: String,
    val bio: String?,  // может быть null
    val avatar: String?
)

fun displayProfile(user: UserProfile?) {
    // Safe call + Elvis operator
    val displayName = user?.name ?: "Anonymous"
    val bio = user?.bio ?: "No bio"
    val avatarUrl = user?.avatar  // может быть null
    
    // Безопасная загрузка изображения
    avatarUrl?.let { url ->
        loadImage(url)
    }
    
    // Альтернативный способ
    if (user != null) {
        // внутри этого блока user точно non-null
        updateUI(user.name, user.bio, user.avatar)
    }
}

// Функция с nullable параметром
fun updateProfile(user: UserProfile?, callback: (Boolean) -> Unit) {
    user?.let {
        // Здесь user гарантировано не null
        val result = saveUserToDatabase(it)
        callback(result)
    } ?: run {
        // Выполнится если user == null
        callback(false)
    }
}

Вложенные nullability проверки

class Repository {
    fun getUserData(id: String): UserData? = /* ... */
}

val repo: Repository? = getRepository()

// Вложенные null проверки - очень удобно
val userName = repo?.let { repository ->
    repository.getUserData("123")?.let { data ->
        data.profile?.let { profile ->
            profile.name
        }
    }
} ?: "No name"

Преимущества null-safety

  • Безопасность на этапе компиляции — ошибки ловятся рано
  • Явность — видно где может быть null
  • Меньше defensive programming — не нужны бесконечные if (x != null) проверки
  • Лучше читаемость кода — intent ясен

Когда использовать !

Not-null assertion (!!) следует использовать осторожно:

// Плохо — может выбросить NPE
val name = user!!.name

// Хорошо — если ты 100% уверен
val id = intent.getStringExtra("id")!!
val bundle = arguments!!  // внутри Fragment ты знаешь что arguments не null

Null-safety — это ключевая особенность Kotlin, которая делает Android приложения более стабильными и надёжными.

Что такое null-safety в Kotlin? | PrepBro