Kotlin ориентируется на безопасность типов и избегание null-указателей, но часто возникает задача отложенной (late) инициализации переменных, например, при использовании dependency injection или в Android Activity. Для этого добавлен модификатор lateinit.
Обычные свойства требуют обязательной инициализации или должны быть nullable, что неудобно, если гарантируется поздняя, но обязательная инициализация. Использование nullable-типа усложняет код и требует дополнительных null-проверок.
lateinit позволяет создать неинициализированное до поры свойство, но обещать компилятору, что оно будет инициализировано до первого использования. Инициировать можно не в конструкторе, а позже.
class UserViewModel { lateinit var repository: UserRepository fun onCreate() { repository = UserRepository() } fun getData() = repository.load() }
Ключевые особенности:
Можно ли применять lateinit для свойств val?
Нет. lateinit работает только с var, так как val должен быть инициализирован один раз немедленно либо через геттер.
Работает ли lateinit с типами Int, Boolean, Double и прочими примитивами?
Нет. Только с объектными ссылочными типами. Для примитивов используйте nullable-типы.
Что произойдет, если обратиться к lateinit свойству до инициализации?
Kotlin бросит UninitializedPropertyAccessException:
lateinit var foo: String println(foo) // Exception
Разработчик объявил lateinit var item: String, не инициализировал до первого вызова метода getItem. Итог: падение приложения.
Плюсы:
Минусы:
Android Activity: lateinit var presenter, инициализация в onCreate. Использование presenter во всех жизненных методах безопасно: nullability не нужен.
Плюсы:
Минусы: