Ответ
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еслиnullable—null) - Элвис-оператор:
nullable?.length ?: 0(значение по умолчанию) - Принудительный вызов:
nullable!!.length(выбросит NPE еслиnullable—null)
Это делает код более предсказуемым и уменьшает количество 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-ошибок — овердохуища меньше. Умная штука, надо пользоваться.