Wenn Sie in Kotlin keine Klasseneigenschaft innerhalb des Konstruktors oder oben im Klassenkörper initialisieren möchten, haben Sie grundsätzlich diese beiden Optionen (aus der Sprachreferenz):
lazy () ist eine Funktion, die ein Lambda verwendet und eine Instanz von Lazy zurückgibt, die als Delegat für die Implementierung einer Lazy-Eigenschaft dienen kann: Der erste Aufruf von get () führt das an Lazy () übergebene Lambda aus und merkt sich das Ergebnis und nachfolgende Aufrufe Um () zu erhalten, geben Sie einfach das gespeicherte Ergebnis zurück.
Beispiel
public class Hello { val myLazyString: String by lazy { "Hello" } }
So den ersten Anruf und die subquential Anrufe, wo auch immer es ist, zu myLazyString zurückkehren wird „Hallo“
Normalerweise müssen Eigenschaften, die als Nicht-Null-Typ deklariert sind, im Konstruktor initialisiert werden. Dies ist jedoch ziemlich oft nicht bequem. Beispielsweise können Eigenschaften durch Abhängigkeitsinjektion oder in der Setup-Methode eines Komponententests initialisiert werden. In diesem Fall können Sie im Konstruktor keinen Initialisierer ungleich Null angeben, möchten jedoch weiterhin Nullprüfungen vermeiden, wenn Sie auf die Eigenschaft im Hauptteil einer Klasse verweisen.
Um diesen Fall zu behandeln, können Sie die Eigenschaft mit dem Modifikator lateinit markieren:
public class MyTest { lateinit var subject: TestSubject @SetUp fun setup() { subject = TestSubject() } @Test fun test() { subject.method() } }
Der Modifikator kann nur für var-Eigenschaften verwendet werden, die im Hauptteil einer Klasse deklariert sind (nicht im primären Konstruktor), und nur, wenn die Eigenschaft keinen benutzerdefinierten Getter oder Setter hat. Der Typ der Eigenschaft darf nicht null sein und darf kein primitiver Typ sein.
Wie kann man also richtig zwischen diesen beiden Optionen wählen, da beide das gleiche Problem lösen können?
lateinit
das Hintergrundfeld mit der Sichtbarkeit des Setters verfügbar gemacht wird, sodass die Art und Weise, wie auf die Eigenschaft von Kotlin und Java aus zugegriffen wird, unterschiedlich ist. Und aus Java-Code kann diese Eigenschaft auchnull
ohne Überprüfung in Kotlin festgelegt werden. Daherlateinit
ist nicht für die verzögerte Initialisierung, sondern für die Initialisierung nicht unbedingt aus Kotlin-Code.