In Kotlin se non vuoi inizializzare una proprietà di classe all'interno del costruttore o nella parte superiore del corpo della classe, hai sostanzialmente queste due opzioni (dal riferimento al linguaggio):
lazy () è una funzione che accetta un lambda e restituisce un'istanza di Lazy che può fungere da delegato per l'implementazione di una proprietà lazy: la prima chiamata a get () esegue il lambda passato a lazy () e ricorda il risultato, chiamate successive per ottenere () restituisce semplicemente il risultato memorizzato.
Esempio
public class Hello { val myLazyString: String by lazy { "Hello" } }
Quindi la prima chiamata e le chiamate secondarie, ovunque si trovino, a myLazyString restituiranno "Hello"
Normalmente, le proprietà dichiarate come di tipo non nullo devono essere inizializzate nel costruttore. Tuttavia, abbastanza spesso questo non è conveniente. Ad esempio, le proprietà possono essere inizializzate tramite l'iniezione delle dipendenze o nel metodo di impostazione di un test unitario. In questo caso, non è possibile fornire un inizializzatore non nullo nel costruttore, ma si desidera comunque evitare controlli null quando si fa riferimento alla proprietà all'interno del corpo di una classe.
Per gestire questo caso, è possibile contrassegnare la proprietà con il modificatore lateinit:
public class MyTest { lateinit var subject: TestSubject @SetUp fun setup() { subject = TestSubject() } @Test fun test() { subject.method() } }
Il modificatore può essere utilizzato solo sulle proprietà var dichiarate all'interno del corpo di una classe (non nel costruttore principale) e solo quando la proprietà non ha un getter o setter personalizzato. Il tipo di proprietà deve essere non nullo e non deve essere di tipo primitivo.
Quindi, come scegliere correttamente tra queste due opzioni, dal momento che entrambi possono risolvere lo stesso problema?
lateinit
espone il suo campo di supporto con la visibilità del setter, quindi i modi in cui si accede alla proprietà da Kotlin e da Java sono diversi. E dal codice Java questa proprietà può essere impostata anche sunull
senza alcun controllo in Kotlin. Pertantolateinit
non è per l'inizializzazione lenta ma per l'inizializzazione non necessariamente dal codice di Kotlin.