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

Ответ

Null-safety в Kotlin — это механизм, предотвращающий NullPointerException (NPE) на этапе компиляции. В Kotlin типы по умолчанию не могут содержать null, если явно не объявлены как nullable с помощью ?.

Пример:

var nonNullable: String = "Hello" // Не может быть null
nonNullable = null // Ошибка компиляции

var nullable: String? = "World" // Может быть null
nullable = null // OK

Обработка nullable:

  • Безопасный вызов: nullable?.length (вернет null если nullablenull)
  • Элвис-оператор: nullable?.length ?: 0 (значение по умолчанию)
  • Принудительный вызов: nullable!!.length (выбросит NPE если nullablenull)

Это делает код более предсказуемым и уменьшает количество runtime-ошибок.

Ответ 18+ 🔞

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

Смотри, как это работает, чувак. В Kotlin, если ты просто объявил переменную, она по умолчанию не может быть null. Вообще. Это как сказать: "Вот тебе стакан, он всегда полный". Попробуй его опустошить — компилятор тебе такую ошибку влепит, что мало не покажется.

var nonNullable: String = "Привет" // Стакан полный, всё норм
nonNullable = null // Ошибка компиляции! Ты чё, мудила, куда воду дел?!

А вот если ты хочешь эту самую возможность иметь пустой стакан, то надо явно попросить. Ставишь вопросительный знак ? — и вуаля, теперь в переменной может быть null. Доверяй, но проверяй, а точнее, доверия ебать ноль, всегда проверяй.

var nullable: String? = "Мир" // Может быть и водой, и пустотой
nullable = null // ОК, стакан-то специальный, nullable-шный

Ну и как с этим жить-то, спросишь? А жить можно по-разному, бля.

Первый способ, самый безопасный — безопасный вызов (?.). Это как осторожно потрогать горячий чайник через полотенце. Если переменная null — просто вернётся null и всё, никакого взрыва. nullable?.length — если в nullable что-то есть, получим длину. Если там null — просто вернётся null. Тихий и мирный исход.

Второй способ — элвис-оператор (?:). Это уже для тех, кто не любит неопределённость. "Либо дай мне значение, либо, хуй с горы, дай мне то, что я скажу!" nullable?.length ?: 0 — если в nullable что-то есть, берём длину. Если там null — получаем ноль. Всё чётко, никаких сюрпризов.

И третий способ, для отчаянных — принудительный вызов (!!). Это когда ты на 146% уверен, что стакан полон, и херачишь его содержимое в себя, не глядя. Но если ты ошибся и там пусто... ну, ёперный театр, получишь свой законный NullPointerException прямо в runtime. nullable!!.length — либо длина, либо тебе пиздец. Рискованно, но иногда оправданно.

Короче, вся эта система сделана для того, чтобы твой код не разваливался в самый неподходящий момент из-за какой-то хуйни. Предсказуемость на уровне, runtime-ошибок — овердохуища меньше. Умная штука, надо пользоваться.