Оператор !!
Принудительное указание Non-Null и связанные риски
«Оператор !!» — бесплатный урок Kotlin Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Kotlin Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Kotlin Academy содержит 4 уроков всего.
Принудительное объявление значения ненулевым
Иногда Вы уверены, что значение, допускающее отсутствие значения, не является нулевым, но компилятор всё равно сообщает об ошибке.
Оператор утверждения ненулевого значения !! сообщает компилятору, что следует Вам доверять и считать значение ненулевым.
Основное использование
Добавление !! преобразует тип, допускающий отсутствие значения, в соответствующий ненулевой тип.
Если значение действительно не является нулевым, код работает точно так же, как обычный вызов.
fun main() {
val name: String? = "Kotlin"
println(name!!.length)
}Опасность
Если значение на самом деле равно null, !! немедленно вызывает NullPointerException.
Это единственное место, где Kotlin позволяет возникнуть NPE, и ответственность за это полностью лежит на Вас.
fun main() {
val name: String? = null
try {
println(name!!.length)
} catch (e: NullPointerException) {
println("Boom: NullPointerException")
}
}Зачем он нужен
Этот оператор намеренно выглядит некрасиво. Два восклицательных знака сразу заметны при проверке кода и указывают на место, где Вы обошли защиту от ошибок.
Он нужен для редких случаев, когда Вы действительно знаете больше, чем компилятор.
Безопасный вызов обычно лучше
В большинстве ситуаций безопасный вызов ?. вместе с оператором Элвиса ?: безопаснее и столь же краток.
Ниже сравниваются два подхода для достижения одной и той же цели.
fun main() {
val name: String? = null
val safeLength = name?.length ?: 0
println(safeLength)
}Не объединяйте !! в цепочку
Никогда не объединяйте несколько операторов !! в цепочку, например a!!.b!!.c. Если произойдёт сбой, Вы не сможете определить, какая именно часть была нулевой.
Разбейте выражение на части или используйте безопасные вызовы.
fun main() {
val text: String? = "hi"
// bad style: text!!.uppercase()!! is hard to debug
val good = text?.uppercase() ?: ""
println(good)
}Допустимое применение
Один из приемлемых случаев — значение, которое Вы установили ранее и которое к этому моменту точно инициализировано.
Даже тогда по возможности отдавайте предпочтение lateinit или изменению структуры кода.
fun main() {
var config: String? = null
config = "loaded"
// we just assigned it, so !! is safe here
println(config!!.uppercase())
}Чтение трассировки стека
Когда !! завершается ошибкой, исключение указывает точную строку. Такая точность — единственное преимущество по сравнению с незаметным получением неправильного результата.
Используйте сообщение, чтобы найти и исправить ошибочное предположение.
fun length(text: String?): Int {
return text!!.length
}
fun main() {
println(length("abc"))
// length(null) would throw on the !! line
}Рефакторинг с удалением !!
Большинство операторов !! можно удалить, если правильно обработать нулевые значения. Ниже резервное значение оператора Элвиса делает функцию полной и защищённой от сбоев.
fun length(text: String?): Int {
return text?.length ?: 0
}
fun main() {
println(length("abc"))
println(length(null))
}Практическое правило
Воспринимайте каждый оператор !! как вопрос: абсолютно ли я уверен, что это значение никогда не будет нулевым?
- Если да и такое происходит редко → допустимо
- Если Вы не уверены → используйте
?.и?:
Объединяем всё
Оператор !! — инструмент, требующий осторожности:
- Он принудительно преобразует тип, допускающий отсутствие значения, в ненулевой тип
- Он вызывает NullPointerException, если значение нулевое
- Почти всегда отдавайте предпочтение безопасным вызовам и оператору Элвиса
fun main() {
val sure: String? = "definitely here"
println(sure!!.length)
val maybe: String? = null
println(maybe?.length ?: -1)
}Быстрая проверка
Проверьте, насколько хорошо Вы понимаете оператор утверждения ненулевого значения.
Итоги
Вы изучили оператор !!:
- Он утверждает, что значение, допускающее отсутствие значения, не является нулевым
- При ошибочном предположении он вызывает NullPointerException
- Его следует использовать в крайнем случае, а не по привычке
Далее Вы узнаете, как значения, допускающие отсутствие значения, приходят из Java через платформенные типы.
Часто задаваемые вопросы
Урок «Оператор !!» бесплатный?
Да — полный текст урока «Оператор !!» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Kotlin Academy, подпишись на CoddyKit PRO. Курс Kotlin Academy содержит 4 уроков всего.
Чему я научусь в уроке «Оператор !!»?
Принудительное указание Non-Null и связанные риски Ты практикуешь Kotlin Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Kotlin Academy?
Предыдущий опыт не требуется. Kotlin Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Оператор !!»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Kotlin Academy?
Да. Каждый урок Kotlin Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.