null — источник боли.Код компилируется, выглядит корректно, а потом падает в рантайме с
NullPointerException.В Kotlin есть управляющие конструкции для работы с
null.Два часто обсуждаемых инструмента — это:
▫️оператор !!
▫️функция
requireNotNull(...).Оператор !!
val value: String? = getValue()
val result = value!!
Оператор !! обещает, что значение точно не будет null.
По сути он говорит компилятору:
«Бро, тут точно not null»
Если ожидание оправдывается — всё работает.
Если значение всё же окажется null — приложение падает с
NullPointerException.Альтернатива — requireNotNull(...)
val result = requireNotNull(value) { "value must not be null" }
requireNotNull работает иначе:▫️явно проверяет значение на null
▫️если значение null, выбрасывает
IllegalArgumentException▫️позволяет задать осмысленное сообщение об ошибке
В отличие от !!, здесь:
▫️проверка не скрыта
▫️ошибка читается как нарушение контракта
▫️сразу понятно, что именно пошло не так
Рассмотрим на примере
Есть метод, который принимает строго not-null параметр:
fun sendEmail(email: String) {
// ...
}
И есть nullable-значение:
val email: String? = user.email
Вариант с !!
sendEmail(email!!)
Мы передаём nullable-значение, уверяя компилятор, что оно точно not null.
Если это окажется не так — получим
NullPointerException без контекста и будем разбираться, где нарушен контракт.Вариант с requireNotNull
sendEmail(
requireNotNull(email) { "User email must not be null" }
)
Здесь ошибка:
▫️возникает в момент передачи параметра
▫️содержит осмысленное сообщение
▫️сразу указывает на причину проблемы
Ключевая мысль
Оба варианта компилируются.
Разница проявляется только в момент ошибки — и именно там она критична.
⁉️ И главный вопрос
Если
requireNotNull закрывает боль с null более правильно,если !! считается «грязным» и потенциально опасным оператором…
Зачем тогда вообще нужен
!! ?Представь, что ты — разработчик языка.
Для каких задач ты бы сознательно оставил такой инструмент?
Это вопрос не про правильно / неправильно и это не вопрос про Kotlin.
Это вопрос про дизайн языка, компромиссы и инструменты, которые он даёт разработчику.
Интересно почитать ваши мысли 👇