Umfassender Leitfaden zur Nullsicherheit in Kotlin

1. Übersicht

In diesem Artikel werden wir uns die Null-Sicherheitsfunktionen ansehen, die in die Kotlin-Sprache integriert sind. Kotlin bietet eine umfassende, native Behandlung von nullbaren Feldern - es werden keine zusätzlichen Bibliotheken benötigt.

2. Maven-Abhängigkeit

Um zu beginnen, müssen Sie die kotlin-stdlib Maven-Abhängigkeit zu Ihrer pom.xml hinzufügen :

 org.jetbrains.kotlin kotlin-stdlib 1.1.1  

Sie finden die neueste Version auf Maven Central.

3. Nullable und Non-Nullable Reference Types

Kotlin verfügt über zwei Arten von Referenzen , die vom Compiler interpretiert werden, um dem Programmierer Informationen über die Richtigkeit eines Programms zur Kompilierungszeit zu geben - diejenigen, die nullbar sind, und diejenigen, die nicht nullbar sind.

Standardmäßig geht Kotlin davon aus, dass der Wert nicht null sein kann :

var a: String = "value" assertEquals(a.length, 5)

Wir können der Referenz a keine Null zuweisen , und wenn Sie dies versuchen, führt dies zu einem Compilerfehler.

Wenn wir eine nullfähige Referenz erstellen möchten, müssen wir das Fragezeichen (?) An die Typdefinition anhängen :

var b: String? = "value"

Danach können wir ihm null zuweisen :

b = null

Wenn wir auf die b- Referenz zugreifen möchten , müssen wir den Null- Fall explizit behandeln , um einen Kompilierungsfehler zu vermeiden, da Kotlin weiß, dass diese Variable null enthalten kann :

if (b != null) { println(b.length) } else { assertNull(b) }

4. Sichere Anrufe

Der Umgang mit jeder nullbaren Referenz auf diese Weise kann umständlich sein. Glücklicherweise hat Kotlin eine Syntax für "sichere Aufrufe" - diese Syntax ermöglicht es Programmierern , eine Aktion nur auszuführen, wenn die spezifische Referenz einen Wert ungleich Null enthält .

Definieren wir zwei Datenklassen, um diese Funktion zu veranschaulichen:

data class Person(val country: Country?) data class Country(val code: String?)

Beachten Sie, dass das Land und Code Felder sind von Nullable - Referenztyp.

Um fließend auf diese Felder zuzugreifen, können wir die sichere Aufrufsyntax verwenden:

val p: Person? = Person(Country("ENG")) val res = p?.country?.code assertEquals(res, "ENG")

Sollte die Variable p eine Null enthalten , gibt die Syntax für sichere Aufrufe ein Null- Ergebnis zurück:

val p: Person? = Person(Country(null)) val res = p?.country?.code assertNull(res)

4.1. Die let () -Methode

Um eine Aktion nur auszuführen, wenn eine Referenz einen nicht nullbaren Wert enthält, können wir einen let- Operator verwenden.

Angenommen, wir haben eine Werteliste und diese Liste enthält auch einen Nullwert :

val firstName = "Tom" val secondName = "Michael" val names: List = listOf(firstName, null, secondName)

Als nächstes können wir eine Aktion für jedes nicht nullbare Element der Namensliste ausführen, indem wir eine let- Funktion verwenden:

var res = listOf() for (item in names) { item?.let { res = res.plus(it) } } assertEquals(2, res.size) assertTrue { res.contains(firstName) } assertTrue { res.contains(secondName) }

4.2. Die auch () Methode

Wenn wir eine zusätzliche Operation anwenden möchten , beispielsweise die Anmeldung für jeden nicht nullbaren Wert, können wir eine also () -Methode verwenden und diese mit einem let () verketten:

var res = listOf() for (item in names) { item?.let { res = res.plus(it); it } ?.also{it -> println("non nullable value: $it")} }

Es wird jedes Element ausgedruckt, das nicht null ist:

non nullable value: Tom non nullable value: Michael

4.3. Die run () -Methode

Kotlin hat eine run () -Methode, um eine Operation für eine nullfähige Referenz auszuführen. Es ist let () sehr ähnlich, aber innerhalb eines Funktionskörpers arbeitet die Run () -Methode mit dieser Referenz anstelle eines Funktionsparameters:

var res = listOf() for (item in names) { item?.run{res = res.plus(this)} }

5. Elvis Operator

Wenn wir eine Referenz haben, möchten wir manchmal einen Standardwert aus der Operation zurückgeben, wenn die Referenz eine Null enthält . Um dies zu erreichen, können wir einen elvis ( ? :) Operator verwenden. Dies entspricht orElse / orElseGet aus der optionalen Java- Klasse:

val value: String? = null val res = value?.length ?: -1 assertEquals(res, -1)

Wenn der Wert Referenz einen NULL-Wert enthält, wobei das Verfahren Länge wird aufgerufen werden:

val value: String? = "name" val res = value?.length ?: -1 assertEquals(res, 4)

6. Nullable Unsafe Get

Kotlin also has an unsafe operator to get a value of a nullable field without handling absence logic explicitly, but it should be used very carefully.

The double exclamation mark operator (!!) takes a value from a nullable reference and throws a NullPointerException if it holds null. This is an equivalent of Optional.get() operation:

var b: String? = "value" b = null assertFailsWith { b!! }

If the nullable reference holds a non-nullable value, the action on that value will be executed successfully:

val b: String? = "value" assertEquals(b!!.length, 5)

7. Filtering Null Values From a List

The List class in Kotlin has a utility method filterNotNull() that returns only non-nullable values from a list that holds nullable references:

val list: List = listOf("a", null, "b") val res = list.filterNotNull() assertEquals(res.size, 2) assertTrue { res.contains("a") } assertTrue { res.contains("b") }

Dies ist ein sehr nützliches Konstrukt, das die Logik kapselt, die wir sonst selbst implementieren müssten.

8. Fazit

In diesem Artikel haben wir Koltins Null-Sicherheitsmerkmale eingehend untersucht. Wir haben Arten von Referenzen gesehen, die Nullwerte enthalten können, und solche, die dies nicht können. Wir haben eine flüssige Nullbehandlungslogik implementiert, indem wir die Funktionen für sichere Anrufe und den elvis- Operator verwendet haben.

Die Implementierung all dieser Beispiele und Codefragmente finden Sie im GitHub-Projekt - dies ist ein Maven-Projekt, daher sollte es einfach zu importieren und auszuführen sein, wie es ist.