Kotlin skupia się na bezpieczeństwie typów i unikaniu wskaźników null, ale często pojawia się potrzeba opóźnionej (late) inicjalizacji zmiennych, na przykład podczas używania wstrzykiwania zależności (dependency injection) lub w Android Activity. Dlatego dodano modyfikator lateinit.
Zwykłe właściwości wymagają obowiązkowej inicjalizacji lub muszą być nullable, co jest niewygodne, jeśli gwarantowana jest późna, ale obowiązkowa inicjalizacja. Użycie typu nullable komplikuje kod i wymaga dodatkowych sprawdzeń null.
lateinit pozwala stworzyć nieinicjalizowaną do czasu właściwość, ale obiecuje kompilatorowi, że zostanie ona zainicjalizowana przed pierwszym użyciem. Inicjować można nie w konstruktorze, a później.
class UserViewModel { lateinit var repository: UserRepository fun onCreate() { repository = UserRepository() } fun getData() = repository.load() }
Kluczowe cechy:
Czy można stosować lateinit dla właściwości val?
Nie. lateinit działa tylko z var, ponieważ val musi być zainicjalizowany raz natychmiast lub przez getter.
Czy lateinit działa z typami Int, Boolean, Double i innymi prymitywami?
Nie. Tylko z typami referencyjnymi. Dla prymitywów użyj typów nullable.
Co się stanie, jeśli odwołasz się do właściwości lateinit przed inicjalizacją?
Kotlin wyrzuci UninitializedPropertyAccessException:
lateinit var foo: String println(foo) // Wyjątek
Programista zadeklarował lateinit var item: String, nie zainicjalizował go przed pierwszym wywołaniem metody getItem. Efekt: zawieszenie aplikacji.
Zalety:
Wady:
Android Activity: lateinit var presenter, inicjalizacja w onCreate. Użycie presenter we wszystkich metodach cyklu życia jest bezpieczne: nie potrzebna jest nullowalność.
Zalety:
Wady: