Шаг 159.
Основы Kotlin.
Инициализация. Поздняя инициализация

    На этом шаге мы рассмотрим организацию такой инициализации.

    Класс Activity в Android представляет экран вашего приложения. Вы не контролируете момент, когда именно будет вызван конструктор Activity. Зато известно, что самая ранняя точка выполнения - это функция с именем onCreate(). Если нельзя инициализировать свойства во время создания экземпляра, то когда это можно сделать?

    Это та ситуация, когда важное значение приобретает поздняя инициализация, и это больше, чем просто нарушение правил инициализации компилятора Kotlin.

    В любое объявление var-свойства можно добавить ключевое слово lateinit. Тогда компилятор Kotlin позволит отложить инициализацию свойства до того момента, когда такая возможность появится.

class Player {
    lateinit var alignment: String
    fun determineFate() {
        alignment = "Good"
    }
    fun proclaimFate() {
        if (::alignment.isInitialized) println(alignment)
    }
}

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

    Ключевое слово lateinit действует как негласный договор: "Я обязуюсь инициализировать эту переменную до первой попытки обратиться к ней". Kotlin предоставляет инструмент для проверки факта инициализации таких переменных: метод isInitialized, показанный в примере выше. Вы можете вызывать isInitialized каждый раз, когда есть сомнения, что переменная lateinit инициализирована, чтобы избежать UninitializedPropertyAccessException.

    Тем не менее isInitialized следует использовать экономно - например, не следует добавлять эту проверку к каждой переменной с поздней инициализацией. Если вы используете isInitialized слишком часто, это, скорее всего, означает, что лучше использовать тип с поддержкой null.

    На следующем шаге мы рассмотрим отложенную инициализацию.




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