Was ist der Kotlin Double-Bang (!!) Operator?

177

Ich konvertiere Java nach Kotlin mit Android Studio. Ich bekomme Doppelknall nach der Instanzvariablen. Was ist der Doppelknall und was noch wichtiger ist, wo ist dies dokumentiert?

mMap!!.addMarker(MarkerOptions().position(london).title("Marker in London"))
mbr_at_ml
quelle

Antworten:

205

Dies ist eine unsichere T?Konvertierung von nullable type ( ) in einen nicht nullable type ( T). !!Wird ausgelöst, NullPointerExceptionwenn der Wert lautet null.

Es ist hier zusammen mit Kotlin-Mitteln der Nullsicherheit dokumentiert .

Hotkey
quelle
1
Was bedeutet es, wenn das !!am Ende einer Aussage steht? IJ Auto- val price = sale.latest!!
Convert
7
@ycomp bedeutet, dass sale.latestenthalten kann null; Die Zuweisung ist nur erfolgreich, wenn sie sale.latestnicht null ist, und wirft andernfalls NPE. Dies gibt Null-Sicherheit für val price: Sein Typ ist nicht Null. Siehe kotlinlang.org/docs/reference/null-safety.html
Hotkey
1
@hotkey: Was ist also der Unterschied zwischen NPE - hier ODER wenn auf die neueste Methode für ein Nullobjekt zugegriffen wird?
Aada
2
@Aada, es ist ein häufiges Problem, eine NPE zu debuggen und Schwierigkeiten zu haben, den Zeilen- / Ausführungspfad zu finden, der den Wert auf null gesetzt hat. Diese Nullzuweisung kann in einem anderen Kontext, einer anderen Klasse oder sogar an einem anderen Tag erfolgen! Durch die Verwendung können !!Sie schnell ausfallen und die Grundursache einer NPE lokalisieren. Ich wünschte, Java hätte eine ähnliche Funktion (dh ohne hässliche ifAussagen und / oder assertIonen).
Cascader
82

Hier ist ein Beispiel, um die Dinge klarer zu machen. Angenommen, Sie haben diese Funktion

fun main(args: Array<String>) {
    var email: String
    email = null
    println(email)
}

Dies führt zu folgendem Kompilierungsfehler.

Null can not be a value of a non-null type String

Jetzt können Sie dies verhindern, indem Sie dem StringTyp ein Fragezeichen hinzufügen , um ihn auf Null zu setzen.

Also haben wir

fun main(args: Array<String>) {
    var email: String?
    email = null
    println(email)
}

Dies ergibt ein Ergebnis von

null

Wenn die Funktion nun eine Ausnahme auslösen soll, wenn der Wert von E-Mail Null ist, können wir am Ende der E-Mail zwei Ausrufezeichen hinzufügen. So was

fun main(args: Array<String>) {
    var email: String?
    email = null
    println(email!!)
}

Dies wird ein werfen KotlinNullPointerException

Alf Moh
quelle
5
Also, warum sollten die Leute '!!' obwohl es unsicher ist, weil eine App beendet wird, wenn diese Variable null hat?
Sam
3
@ David Sie können es nur verwenden, wenn Sie 100% sicher sind, dass die Variable nicht null ist (z. B. Sie haben es explizit überprüft) und Sie eine nicht nullfähige Variable benötigen
FMK
7
@ FMK Ich verstehe, danke! Ich verstehe, dass Double Bang verwendet wird, um es möglich zu machen, dass die Werte der Variablen nullable type in Variablen variabler Typen umgewandelt werden, oder?
Sam
2
@ David ja genau.
FMK
10

Double-Bang-Operator ist eine ausgezeichnete Option für Fans von NullPointerException(oder kurz NPE).

Der Nicht-Null-Assertionsoperator !! konvertiert einen beliebigen Wert in einen Nicht-Null-Typ und löst eine Ausnahme aus, wenn der Wert Null ist.

val nonNull = a!!.length

Sie können also schreiben a!!, und dies gibt einen Nicht-Null-Wert von a( Stringhier zum Beispiel) zurück oder wirft eine NPE, wenn aNull ist.

Wenn Sie eine NPE wollen, können Sie sie haben, aber Sie müssen explizit danach fragen. Dieser Operator sollte in Fällen verwendet werden, in denen der Entwickler garantiert - der Wert wird niemals null sein .

Andy Fedoroff
quelle
2
Als Anfänger fragen: Warum sollte ich einen Wert in einen Nicht-Null-Typ konvertieren wollen?
Wolf359
4
@ Wolf359 Damit können Sie 100% sicher sein, dass der Wert nicht null ist. ("Es ist ein häufiges Problem, eine NPE zu debuggen und Schwierigkeiten zu haben, den Zeilen- / Ausführungspfad zu finden, der den Wert auf null gesetzt hat. Diese Nullzuweisung kann in einem anderen Kontext, einer anderen Klasse oder sogar an einem anderen Tag erfolgen!" von Cascader)
Reduzierung der Aktivität