0Pricing
Android Academy · Урок

Как избежать NullPointerExceptions

Шаблоны безопасного кода.

«Как избежать NullPointerExceptions» — бесплатный урок Android Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Android Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Android Academy содержит 4 уроков всего.

Цель: никаких NPE

NullPointerException, или NPE, возникает, когда код использует значение, которое на самом деле равно null. Kotlin создан так, чтобы такие ситуации возникали редко.

В этом уроке объединяются изученные Вами инструменты и рассматриваются несколько способов, которыми NPE всё же может возникнуть.

Оператор !!

Утверждение о ненулевом значении !! сообщает компилятору, что значение точно не равно null. Если это неверно, возникает NPE.

Этот оператор отключает безопасность, поэтому используйте его редко и только при полной уверенности.

fun main() {
    val name: String? = "Ada"
    println(name!!.length)  // works, name is not null
}

!! может вызвать сбой

Если значение действительно равно null, !! вызывает NullPointerException именно в этой строке.

Это основной способ вновь столкнуться с проблемой, от которой защищает Kotlin. Избегайте !!, если можно использовать безопасный вызов или оператор Элвиса.

val name: String? = null
println(name!!.length)
// throws KotlinNullPointerException

Предпочитайте безопасные альтернативы

Практически любое использование !! можно переписать с помощью ?. и ?:. Безопасный вариант не может вызвать сбой.

Сравните ниже рискованный и безопасный варианты.

// Risky:
val len1 = name!!.length
// Safe:
val len2 = name?.length ?: 0

Проверяйте заранее

Обрабатывайте null на границе кода, а внутри работайте с ненулевыми значениями. Используйте Элвиса с return или throw, чтобы сразу отклонить отсутствующий входной параметр.

После такой проверки тип значения автоматически считается ненулевым.

fun length(s: String?): Int {
    val text = s ?: return 0
    return text.length
}

requireNotNull

Если null действительно означает ошибку в программе, requireNotNull выдаёт понятную ошибку и возвращает ненулевое значение.

Эта функция информативнее, чем !!, поскольку Вы можете добавить сообщение.

fun start(config: String?) {
    val c = requireNotNull(config) { "config missing" }
    println(c.length)
}

Платформенные типы из Java

Значения, поступающие из Java, имеют неизвестную допустимость null и называются платформенными типами. Kotlin не может гарантировать, что они не равны null.

При использовании библиотек Java явно объявляйте ожидаемый тип и предусмотрительно обрабатывайте null.

// From Java: String maybe = obj.getName();
val name: String? = obj.name  // be safe
println(name?.length ?: 0)

Проблема lateinit

lateinit var позволяет отложить инициализацию ненулевого свойства. Но обращение к нему до присваивания вызывает исключение.

Используйте lateinit только в том случае, если уверены, что значение будет задано до любого обращения к нему.

lateinit var config: String
fun read() {
    println(config.length)
    // crashes if config was never set
}

Значения по умолчанию вместо null

Часто допустимости null можно полностью избежать, выбрав разумное значение по умолчанию. Пустая строка или пустой список нередко лучше, чем null.

Чем меньше типов, допускающих null, тем меньше вероятность возникновения NPE.

fun main() {
    val tags: List<String> = emptyList()
    println(tags.size)  // 0, never null
}

Безопасная цепочка обработки

Эта программа считывает необязательное значение, безопасно преобразует его и всегда выдаёт результат. Никаких !! и сбоев.

Именно к такому стилю следует стремиться в настоящем коде Android.

fun main() {
    val input: String? = null
    val result = input?.trim()?.uppercase() ?: "N/A"
    println(result)  // prints: N/A
}

Рекомендации

Предпочитайте ненулевые типы, обрабатывайте null на границах с помощью Элвиса и используйте ?.let для необязательных действий. Оставляйте !! для редких случаев, когда null невозможен.

Следуйте этим правилам, и NullPointerExceptions останутся в прошлом.

val safe = data?.value ?: default
data?.let { handle(it) }

Быстрая проверка

Проверьте, насколько хорошо Вы поняли способы предотвращения NullPointerExceptions.

Краткое повторение

NPE в Kotlin обычно возникают из-за !!, платформенных типов из Java или неинициализированных значений lateinit. Избегайте их, предпочитая ненулевые типы и безопасные операторы.

Используйте ?., ?:, ?.let и проверку с помощью requireNotNull, чтобы код не приводил к сбоям. Теперь Вы изучили основные принципы безопасной работы с null в Kotlin.

Часто задаваемые вопросы

Урок «Как избежать NullPointerExceptions» бесплатный?

Да — полный текст урока «Как избежать NullPointerExceptions» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Android Academy, подпишись на CoddyKit PRO. Курс Android Academy содержит 4 уроков всего.

Чему я научусь в уроке «Как избежать NullPointerExceptions»?

Шаблоны безопасного кода. Ты практикуешь Android Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Android Academy?

Предыдущий опыт не требуется. Android Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Как избежать NullPointerExceptions»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Android Academy?

Да. Каждый урок Android Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Допускающие null и ненулевые типы
  2. Безопасные вызовы и Elvis
  3. Функции let, also и области видимости
  4. Как избежать NullPointerExceptions
← Назад к Android Academy