Kotlin реализует безопасную работу с null за счёт системы типов: любой тип по умолчанию не может быть null, например, val a: String = null вызовет ошибку компиляции. Для обозначения возможности присвоить null используется символ вопроса ?, например:
val name: String? = null
Для работы с Nullable-типами предоставляются:
?., который возвращает null, если объект сам null, и вызывает метод/поле в противном случае: name?.length.?:, чтобы задать значение по умолчанию, если слева — null: val length = name?.length ?: 0if (name != null) { println(name.length) }
NullPointerException, если объект — null (используется крайне аккуратно):val length = name!!.length
Лучшие практики: минимизировать Nullable-типы, использовать Safe-call и Elvis оператор, избегать !!, явно моделировать ситуации, когда null допустим.
Можно ли присвоить типу
val a: Stringзначение null, и как этого избежать?
Ответ: Нет, по умолчанию в Kotlin типы не могут быть равны null. Чтобы позволить присваивание null, надо явно указать val a: String? = null. Типы без ? всегда non-null.
История
В проекте банковского приложения переменная типа
Userхранила результат поиска клиента. Разработчик определилvar user: User, но иногда клиент не находился и сервис возвращал null. Это вызывало NPE и массовые краши.
История
В чат-боте для поддержки использовали !! для доступа к сообщениям пользователя (
message!!.text), считая что сообщения всегда приходят. Бот падал на первом же пустом сообщении. Safe-call бы избавил от проблемы.
История
В мобильном приложении данные из базы могли быть не загружены и приходили как null. Вместо безопасного обращения разработчик использовал прямой доступ, что приводило к крэшам во всех случаях неполных данных.