У Kotlin, якщо ви не хочете ініціалізувати властивість класу всередині конструктора або у верхній частині корпусу класу, у вас є в основному ці два варіанти (з мовної посилання):
lazy () - це функція, яка приймає лямбда і повертає екземпляр Lazy, який може служити делегатом для реалізації властивості lazy: перший виклик get () виконує передану лямбду в lazy () і запам'ятовує результат, наступні дзвінки щоб отримати () просто повернути запам'ятовуваний результат.
Приклад
public class Hello { val myLazyString: String by lazy { "Hello" } }
Тож перший дзвінок та підпорядкові дзвінки, де б він не був, до myLazyString повернеться "Привіт"
Зазвичай властивості, оголошені як ненульові, повинні бути ініціалізовані в конструкторі. Однак досить часто це не зручно. Наприклад, властивості можна ініціалізувати за допомогою ін'єкції залежності або методом налаштування одиничного тесту. У цьому випадку ви не можете подати ненульовий ініціалізатор у конструктор, але ви все одно хочете уникати нульових перевірок при посиланні на властивість всередині тіла класу.
Для вирішення цього випадку ви можете позначити властивість за допомогою модифікатора lateinit:
public class MyTest { lateinit var subject: TestSubject @SetUp fun setup() { subject = TestSubject() } @Test fun test() { subject.method() } }
Модифікатор може бути використаний лише для властивостей var, оголошених всередині тіла класу (не в первинному конструкторі), і лише тоді, коли у властивості немає спеціального геттера або сеттера. Тип властивості повинен бути ненульовим, і він не повинен бути примітивним типом.
Отже, як правильно вибрати між цими двома варіантами, оскільки обидва вони можуть вирішити одну і ту ж проблему?
lateinit
відкриває поле резервного зберігання з видимістю сетера, тому способи доступу до власності від Kotlin та Java відрізняються. І з коду Java цю властивість можна встановити навітьnull
без будь-яких перевірок у Kotlin. Томуlateinit
не для лінивої ініціалізації, але для ініціалізації не обов'язково з коду Котліна.