Kotlin - Inicialização de propriedade usando "by lazy" vs. "lateinit"

No Kotlin, se você não deseja inicializar uma propriedade de classe dentro do construtor ou na parte superior do corpo da classe, você tem basicamente essas duas opções (da referência de idioma):

Inicialização lenta

lazy () é uma função que pega um lambda e retorna uma instância do Lazy que pode servir como um delegado para implementar uma propriedade preguiçosa: a primeira chamada a get () executa o lambda passado a lazy () e lembra o resultado, chamadas subseqüentes para obter (), simplesmente retorne o resultado lembrado.

Exemplo

public class Hello {

   val myLazyString: String by lazy { "Hello" }

}

Portanto, a primeira chamada e as chamadas subquenciais, onde quer que estejam, paramyLazyString retornará"Olá"

Inicialização tardia

Normalmente, as propriedades declaradas como tendo um tipo não nulo devem ser inicializadas no construtor. No entanto, com bastante frequência isso não é conveniente. Por exemplo, as propriedades podem ser inicializadas por injeção de dependência ou no método de configuração de um teste de unidade. Nesse caso, você não pode fornecer um inicializador não nulo no construtor, mas ainda assim deseja evitar verificações nulas ao fazer referência à propriedade dentro do corpo de uma classe.

Para lidar com esse caso, você pode marcar a propriedade com o modificador lateinit:

public class MyTest {

   lateinit var subject: TestSubject

   @SetUp fun setup() { subject = TestSubject() }

   @Test fun test() { subject.method() }
}

O modificador pode ser usado apenas em propriedades var declaradas dentro do corpo de uma classe (não no construtor primário) e somente quando a propriedade não possui um getter ou setter personalizado. O tipo da propriedade deve ser não nulo e não deve ser um tipo primitivo.

Então, como escolher corretamente entre essas duas opções, pois ambas podem resolver o mesmo problema?

questionAnswers(6)

yourAnswerToTheQuestion