2016-08-04 10 views
19

In der Kotlin-Sprache müssen wir standardmäßig jede Variable initialisieren, wenn sie eingeführt wird. Um dies zu vermeiden, kann das Schlüsselwort lateinit verwendet werden. Das Verweisen auf eine lateinit Variable, bevor sie initialisiert wurde, führt zu einer Laufzeitausnahme.Warum erlaubt Kotlin nicht, Latetinit mit primitiven Typen zu verwenden?

lateinit kann jedoch nicht mit den primitiven Typen verwendet werden. Wieso ist es so?

Antwort

16

Für Objekttypen, Kotlin verwendet den null Wert zu markieren, dass eine lateinit Eigenschaft wird nicht initialisiert und die entsprechende Ausnahme zu werfen, wenn die Eigentum wird zugegriffen.

Für primitive Typen gibt es keinen solchen Wert, daher gibt es keine Möglichkeit, eine Eigenschaft als nicht initialisiert zu markieren und die Diagnose bereitzustellen, die lateinit bereitstellen muss. (Wir könnten versuchen, einen separaten Marker irgendeiner Art zu verwenden, aber dieser Marker würde nicht aktualisiert, wenn das Feld durch Reflexion initialisiert wird, was ein Hauptanwendungsfall von lateinit ist).

Daher wird lateinit nur für Eigenschaften von Objekttypen unterstützt.

+31

Könnten Sie in der Antwort klären, warum 'laterinit Int' im Runtime nicht mit dem Typ 'Integer' dargestellt werden konnte, der den Wert' null 'enthalten kann, obwohl er nicht initialisiert wurde? – Ilya

+0

@Ilya, weil ein 'Integer' kein' int' ist. Es ist ein Boxed-Typ, und es spielt eine Rolle, wenn das Material nativ oder durch Reflektion eingestellt wird. –

+2

Also, ich denke, Kotlin wickelt die primitiven Typen zum Objekt auf (zum Beispiel Int zu Int). Warum kann Int jedoch nicht null enthalten, weil es ein Objekt ist? Warum können wir einen Parameter auch nicht als NULL-Wert deklarieren und ihn später eingeben? (var x: Int?) – Yao

1

Eine kurze Antwort ist, dass Sie bei Primitiven immer 0 als Standard verwenden können und standardmäßig Nullwerte null. Nur nicht nullfähige nicht-primitive Typen müssen möglicherweise lateinit umgehen, um das Typsicherheitssystem zu umgehen.

Eigentlich gibt es keine Notwendigkeit für eine Variable in Kotlin Initialisierung, solange sie einen Wert vor den ersten Zugriff hat, und es kann statisch nachgewiesen werden. Was bedeutet dieser Code vollkommen gültig ist:

fun main(args: Array<String>) { 
    var x: Int 
    val y: Double 

    x = 0 
    y = x + 0.1 

    println("$x, $y") 
} 

Aber es gibt (seltenen) Fällen, wenn die Initialisierung nicht statisch nachgewiesen werden kann. Der häufigste Fall ist ein Klasse-Feld, das jede Form von Dependency Injection verwendet:

class Window { 
    @Inject lateinit parent: Parent 
} 
Verwandte Themen