Kotlin
Null Sicherheit
Suche…
Nullable- und Non-Nullable-Typen
Normale Typen wie String
sind nicht nullfähig. Damit sie in der Lage sind, Nullwerte zu enthalten, muss dies explizit angegeben werden, indem ein ?
dahinter: String?
var string : String = "Hello World!" var nullableString: String? = null string = nullableString // Compiler error: Can't assign nullable to non-nullable type. nullableString = string // This will work however!
Safe Call Operator
Um auf Funktionen und Eigenschaften von nullfähigen Typen zuzugreifen, müssen Sie spezielle Operatoren verwenden.
Der erste ?.
gibt Ihnen die Eigenschaft oder Funktion, auf die Sie zugreifen möchten, oder null, wenn das Objekt null ist:
val string: String? = "Hello World!" print(string.length) // Compile error: Can't directly access property of nullable type. print(string?.length) // Will print the string's length, or "null" if the string is null.
Idiom: Aufrufen mehrerer Methoden für dasselbe, auf Null überprüfte Objekt
Eine elegante Methode zum Aufrufen mehrerer Methoden eines nullgeprüften Objekts ist die Verwendung von Kotlins apply
wie folgt:
obj?.apply {
foo()
bar()
}
Dies ruft foo
und bar
auf obj
(was this
in der apply
Block) nur dann , wenn obj
nicht-Null ist, andernfalls den gesamten Block zu überspringen.
Um eine nullfähige Variable als nicht-nullfähige Referenz in den Gültigkeitsbereich zu bringen, ohne sie zum impliziten Empfänger von Funktions- und Eigenschaftsaufrufen zu machen, können Sie let
statt apply
:
nullable?.let { notnull ->
notnull.foo()
notnull.bar()
}
notnull
könnte etwas genannt, oder sogar weggelassen und durch verwenden die impliziten Lambda - Parameter it
.
Intelligente Besetzungen
Wenn der Compiler feststellen kann, dass ein Objekt an einem bestimmten Punkt nicht null sein kann, müssen Sie keine speziellen Operatoren mehr verwenden:
var string: String? = "Hello!"
print(string.length) // Compile error
if(string != null) {
// The compiler now knows that string can't be null
print(string.length) // It works now!
}
Hinweis: Mit dem Compiler können Sie keine veränderlichen Variablen für das Umwandeln von Variablen verwenden, die möglicherweise zwischen der Nullprüfung und der beabsichtigten Verwendung geändert werden.
Wenn auf eine Variable außerhalb des Gültigkeitsbereichs des aktuellen Blocks zugegriffen werden kann (z. B. weil sie Mitglieder eines nichtlokalen Objekts ist), müssen Sie eine neue lokale Referenz erstellen, die Sie anschließend mit einem Cast umsetzen und verwenden können.
Beseitigen Sie Nullen aus einem Iterable-Array und einem Array
Manchmal müssen wir den Typ von Collection<T?>
Collections<T>
ändern. In diesem Fall ist filterNotNull
unsere Lösung.
val a: List<Int?> = listOf(1, 2, 3, null)
val b: List<Int> = a.filterNotNull()
Null Coalescing / Elvis Operator
Manchmal ist es wünschenswert, einen auswertbaren Ausdruck auf eine wenn-andere Weise auszuwerten. Der elvis-Operator ?:
Kann für eine solche Situation in Kotlin verwendet werden.
Zum Beispiel:
val value: String = data?.first() ?: "Nothing here."
Der obige Ausdruck gibt "Nothing here"
wenn data?.first()
oder data
selbst einen null
, andernfalls das Ergebnis von data?.first()
Es ist auch möglich, Ausnahmen mit derselben Syntax auszulösen, um die Codeausführung abzubrechen.
val value: String = data?.second()
?: throw IllegalArgumentException("Value can't be null!")
Erinnerung: Mit dem Assertion-Operator können NullPointerExceptions ausgelöst werden (zB
data!!.second()!!
)
Behauptung
!!
Suffixe ignorieren die Nullfähigkeit und geben eine nicht-null-Version dieses Typs zurück. KotlinNullPointerException
wird ausgelöst, wenn das Objekt eine null
.
val message: String? = null
println(message!!) //KotlinNullPointerException thrown, app crashes
Elvis Operator (? :)
In Kotlin können wir eine Variable deklarieren, die eine null reference
. Angenommen, wir haben eine nullfähige Referenz a
, wir können sagen: "Wenn a
nicht null ist, verwenden Sie es, andernfalls verwenden Sie einen Nicht-Nullwert x
".
var a: String? = "Nullable String Value"
Nun, a
kann null sein. Wenn wir also auf den Wert von a
zugreifen müssen, müssen wir eine Sicherheitsüberprüfung durchführen, ob der Wert einen Wert enthält oder nicht. Wir können diese Sicherheitsüberprüfung mit einer konventionellen if...else
Anweisung durchführen.
val b: Int = if (a != null) a.length else -1
Aber hier kommt Voraus Operator Elvis
(Operator Elvis: ?:
). Oben if...else
kann mit dem Elvis-Operator wie folgt ausgedrückt werden:
val b = a?.length ?: -1
Wenn der Ausdruck links von ?:
(Hier: a?.length
) nicht null ist, gibt der elvis-Operator ihn zurück, andernfalls den Ausdruck nach rechts (hier: -1
). Der Ausdruck auf der rechten Seite wird nur ausgewertet, wenn die linke Seite null ist.