Шаг 62.
Основы Kotlin.
Null-безопасность и исключения. Nullability

    На этом шаге мы поясним, что такое null и чем это значение отличается, например, от пустой строки.

    Некоторым элементам в Kotlin может быть присвоено значение null, а другим нет. Первые - это nullable (null возможен), а вторые - это non-nullable. Например, переменная в NyetHack с признаком наличия скакуна у игрока должна поддерживать значение null, так как скакун есть не у каждого игрока. Однако переменная с количеством очков здоровья точно не должна принимать значение null. Каждый игрок должен иметь определенное количество очков здоровья, иное просто нелогично. Да, значение переменной может быть равно 0, но 0 - это не null. Null - это отсутствие значения.

    Откройте NyetHack и создайте новый файл с именем Tavern.kt. Добавьте функцию main(), с которой будет начинаться выполнение кода.

    Прежде чем открыть таверну для клиентов, проведем эксперимент. Добавьте в main() переменную var и присвойте ей значение, а затем присвойте ей значение null.

fun main() {
    var signatureDrink = "Buttered Ale"
    signatureDrink = null
}


Рис.1. Повторное присваивание значения null переменной var (Tavern.kt)

    Еще до запуска кода IntelliJ предупредит красным подчеркиванием, что что-то не так. Запустите код:

  Null can not be a value of a non-null type String


Рис.2. Результат работы приложения

    Kotlin не позволил присвоить значение null переменной signatureDrink, потому что эта переменная имеет тип, не поддерживающий null (строка, String). Тип String не поддерживает значение null. Текущее объявление гарантирует, что signatureDrink будет хранить строку, а не null.

    Если ранее вы работали с Java, то заметите, что это поведение отличается от привычного. В Java такой код разрешен, например:

  String signatureDrink = "Buttered Ale"; 
  signatureDrink = null;

    Повторное присваивание signatureDrink значения null - это нормально для Java. Но как вы думаете, что случится, если попробовать на Java провести конкатенацию строки с переменной signatureDrink?

  String signatureDrink = "Buttered Ale"; 
  signatureDrink = null;
  signatureDrink = signatureDrink + ", large";

    Этот код вызовет исключение NullPointerException, которое, в свою очередь, остановит программу.

    Код Java дает сбой, потому что в операции конкатенации участвует несуществующая строка. Это недопустимая операция.


Если вы не понимаете, почему значение null в строковой переменной это не то же самое, что пустая строка, то этот пример все разъяснит. Значение null подразумевает, что переменной не существует. Пустая строка означает, что переменная существует и имеет значение "", которое можно объединить с ", large".

    Java и многие другие языки поддерживают такую инструкцию на псевдокоде: "Эй, несуществующая строка, выполни конкатенацию строк!" В этих языках переменная может иметь значение null (кроме примитивов, которые Kotlin не поддерживает). В таких языках, которые допускают null для любого типа, ошибка NullPointerException является частой причиной сбоя приложения.

    Kotlin принимает противоположную позицию в обращении с null. Если не указано иное, то переменной нельзя присвоить значение null. Это предотвращает проблемы "Эй, несуществующий элемент, сделай что-нибудь" еще во время компиляции, а не в момент выполнения программы.

    На следующем шаге мы рассмотрим явный тип null в Kotlin.




Предыдущий шаг Содержание Следующий шаг