Come dimostrato dalla D3xter si ha la possibilità di impostare nel costruttore. Hai anche altre opzioni. Qui tutti sono ...
creare la proprietà all'interno del costruttore (come da @ D3xter), questo è il caso più comune per le proprietà semplici inizializzati direttamente dal costruttore principale:
class TestClass(private val context: Context) {
fun doSomeVoodoo() {
val text : String = context.getString()
}
}
È possibile dichiarare la proprietà val
e non inizializzarla, supponendo che tutti i possibili costruttori lo inizino effettivamente (come nel secondo esempio nella domanda che si sta facendo). Questo è normale quando si dispone di più di un costruttore che potrebbe inizializzare un valore diverso:
public class TestClass {
private val context: Context
public constructor(context : Context) {
this.context = context
}
// alternative constructor
public constructor(pre: PreContext) {
this.context = pre.readContext()
}
public fun doSomeVoodoo() {
val text : String = context.getString()
}
}
È possibile passare in parametri del costruttore che non sono dichiarazioni di proprietà, e quindi utilizzare quelli all'interno inizializzazioni di proprietà. Questo è comune quando si dispone di inizializzazione più complessi o necessità di utilizzare le proprietà delegati:
class TestClass(context: PreContext) {
private val context : Context by lazy { context.readContext() }
private val other: List<Items> = run {
context.items.map { it.tag }.filterNotNull()
}
private val simpleThing = context.getSimple()
fun doSomeVoodoo() {
val text : String = context.getString()
}
}
Utilizzando lateinit
modifier quando non è possibile inizializzare il valore durante la costruzione, ma si è sicuri che sarà fatto prima del primo accesso in lettura. Questo è comune quando un'iniezione di dipendenza, contenitore CIO, o qualcosa del genere crea una versione vuota della classe e poi inizializza immediatamente:
class TestClass() {
private lateinit var context : Context // set by something else after construction
fun doSomeVoodoo() {
val text : String = context.getString()
}
}
Per lateinit
la proprietà deve attualmente essere un var
e non funziona con primitiva tipi.
È anche possibile dichiarare una proprietà var
e non inizializzarla se si utilizza un delegato progettato a tale scopo, ad esempio Delegates.notNull()
.Questo è simile a lateinit
e comune quando si desidera un var
che non ha stato iniziale, ma è impostato più tardi, dopo la costruzione al punto sconosciuto in tempo:
public class TestClass() {
private var context: Context by Delegates.notNull()
public fun doSomeVoodoo() {
// if context is not set before this is called, an exception is thrown
val text : String = context.getString()
}
}
Il secondo esempio sta lavorando con Kotlin 0.12.213. Che versione di Kotlin stai usando? – D3xter
Funziona. Ho già usato 0.12.613. Ma penso, stavo facendo qualcosa di sbagliato. Scusate! – Christopher
Ci sono più casi disponibili, ho aggiunto una risposta per una copertura completa. –