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):
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, para myLazyString retornarão "Hello"
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 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 só pode ser usado 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?
lateinit
expõe seu campo de suporte com visibilidade do setter, de modo que as maneiras pelas quais a propriedade é acessada no Kotlin e no Java são diferentes. E a partir do código Java, essa propriedade pode ser configurada mesmonull
sem nenhuma verificação no Kotlin. Portanto,lateinit
não é para a inicialização lenta, mas para a inicialização não necessariamente do código Kotlin.