Kotlin - Инициализация свойств с использованием «ленивый» против «lateinit»

В Kotlin, если вы не хотите инициализировать свойство класса внутри конструктора или в верхней части тела класса, у вас есть в основном эти две опции (из ссылки на язык):

Ленивая инициализация

lazy () - это функция, которая принимает лямбду и возвращает экземпляр Lazy, который может служить делегатом для реализации свойства lazy: первый вызов get () выполняет лямбду, переданную в lazy (), и запоминает результат, последующие вызовы get () просто возвращает запомненный результат.

пример

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, объявленных внутри тела класса (не в основном конструкторе), и только в том случае, если у свойства нет пользовательского метода получения или установки. Тип свойства должен быть ненулевым, и это не должен быть примитивный тип.

Итак, как правильно выбрать один из этих двух вариантов, поскольку оба они могут решить одну и ту же проблему?