JavaRush /Java-Blog /Random-DE /Kaffeepause Nr. 161. So behandeln Sie Null in Java mithil...

Kaffeepause Nr. 161. So behandeln Sie Null in Java mithilfe von Optional

Veröffentlicht in der Gruppe Random-DE
Quelle: Medium Dieser Artikel hilft Ihnen, den Zweck von Optional bei der Arbeit mit Java-Code besser zu verstehen. Kaffeepause Nr. 161.  So behandeln Sie Null in Java mit Optional - 1Als ich anfing, mit Java-Code zu arbeiten, wurde mir oft empfohlen, Optional zu verwenden. Aber damals hatte ich wenig Verständnis dafür, warum die Verwendung von Optional besser war als die Implementierung der Behandlung für Nullwerte. In diesem Artikel möchte ich mit Ihnen teilen, warum ich denke, dass wir alle optional mehr verwenden sollten und wie Sie eine übermäßige Optionalisierung Ihres Codes vermeiden können, die sich nachteilig auf die Codequalität auswirkt.

Was ist optional?

Der optionale Parameter wird verwendet, um Objekte zu übertragen und die Verarbeitung von Nullreferenzen durch verschiedene APIs zu ermöglichen. Schauen wir uns den Codeausschnitt an:
Coffee coffee = new Coffee();
Integer quantity = coffee.getSugar().getQuantity();
Wir haben eine Coffee- Instanz , in der wir etwas Zucker aus einer Instanz des Sugar- Objekts erhalten . Wenn wir davon ausgehen, dass der Mengenwert nie im Coffee- Konstruktor festgelegt wurde , gibt Coffee.getSugar().getQuantity() eine NullPointerException zurück . Natürlich können wir immer die guten alten Nullprüfungen verwenden , um das Problem zu beheben.
Coffee coffee = new Coffee();
Integer quantity = 0;
if (coffee.getSugar() != null) {
  quantity = coffee.getSugar().getQuantity();
}
Jetzt scheint alles in Ordnung zu sein. Beim Schreiben von Java-Code sollten wir jedoch besser auf die Implementierung von Nullprüfungen verzichten . Sehen wir uns an, wie dies mit Optional erfolgen kann.

So erstellen Sie optional

Es gibt drei Möglichkeiten, optionale Objekte zu erstellen:
  • of(T value) – Instanziierung eines optionalen Nicht-Null-Objekts. Beachten Sie, dass die Verwendung von of() zum Verweisen auf ein Nullobjekt eine NullPointerException auslöst .

  • ofNullable(T-Wert) – erstellt einen optionalen Wert für ein Objekt, der null sein kann.

  • empty() – Erstellt eine optionale Instanz, die einen Verweis auf null darstellt .

// пример использования Optional.of(T Value)
String name = "foo";
Optional<String> stringExample = Optional.of(name)
// пример использования Optional.ofNullable(T Value)
Integer age = null;
Optional<Integer> integerExample= Optional.ofNullable(age)
// пример использования Optional.empty()
Optional<Object> emptyExample = Optional.empty();
Sie haben also ein optionales Objekt. Schauen wir uns nun die beiden Hauptmethoden für Optional an:
  • isPresent() – Diese Methode sagt Ihnen, ob das optionale Objekt einen Wert ungleich Null enthält.

  • get() – Ruft den Wert für Optional mit dem aktuellen Wert ab. Beachten Sie, dass der Aufruf von get() für ein leeres Optional zu einer NullPointerException führt .

Bitte beachten Sie, dass Sie etwas verpassen, wenn Sie bei der Arbeit mit Optional nur get() und isPresent() verwenden! Um dies zu verstehen, schreiben wir nun das obige Beispiel mit Optional um.

Verbesserung der Nullprüfung mit Optional

Wie können wir also den obigen Code verbessern? Mit Optional können wir die Anwesenheit eines Objekts mit isPresent() verstehen und es mit get() abrufen . Beginnen wir damit, das Ergebnis von Coffee.getSugar() mit Optional zu verpacken und die Methode isPresent() zu verwenden . Dies hilft uns festzustellen, ob getSugar() null zurückgibt.
Coffee coffee = new Coffee();
Optional<String> sugar = Optional.ofNullable(coffee.getSugar());
int quantity = 0;
if (sugar.isPresent()) {
  Sugar sugar = sugar.get();
  int quantity = sugar.getQuantity();
}
Wenn man sich dieses Beispiel ansieht, scheint das Packen des Ergebnisses von Coffee.getSugar() in Optional keinen Mehrwert zu bringen, sondern eher den Aufwand zu erhöhen. Wir können das Ergebnis verbessern, indem wir meine Lieblingsfunktionen aus der Optional-Klasse verwenden:
  • map(Function<? super T,? erweitert U> Mapper) – Ordnet den in Optional enthaltenen Wert der bereitgestellten Funktion zu. Wenn der optionale Parameter leer ist, gibt map() Optional.empty() zurück .

  • orElse(T other) ist eine „spezielle“ Version der get()- Methode . Es kann den in Optional enthaltenen Wert abrufen. Im Falle eines leeren Optionals wird jedoch der an die orElse() -Methode übergebene Wert zurückgegeben .

Die Methode gibt den in der optionalen Instanz enthaltenen Wert zurück. Wenn der optionale Parameter jedoch leer ist, also keinen Wert enthält, gibt orElse() den an seine Methodensignatur übergebenen Wert zurück, der als Standardwert bezeichnet wird.
Coffee coffee = new Coffee();

Integer quantity = Optional.ofNullable(coffee.getSugar())
    .map(it -> it.getQuantity())
    .orElse(0);
Das ist wirklich cool – zumindest finde ich das. Wenn wir nun im Falle eines leeren Werts nicht den Standardwert zurückgeben möchten, müssen wir eine Ausnahme auslösen. orElseThrow (Supplier<? extensions
Coffee coffee = new Coffee();

Integer quantity = Optional.ofNullable(coffee.getSugar())
  .map(it -> it.getQuantity())
  .orElseThrow(IllegalArgumentException::new);
Wie Sie sehen, bietet Optional mehrere Vorteile:
  • abstrakte Nullprüfungen
  • stellt eine API zum Umgang mit Nullobjekten bereit
  • ermöglicht es dem deklarativen Ansatz, auszudrücken, was erreicht wird

So werden Sie mit Optional effektiv

In meiner Arbeit verwende ich Optional als Rückgabetyp, wenn eine Methode den Status „Kein Ergebnis“ zurückgeben kann. Normalerweise verwende ich es, wenn ich Rückgabetypen für Methoden definiere.
Optional<Coffee> findByName(String name) {
   ...
}
Manchmal ist dies nicht notwendig. Wenn ich zum Beispiel eine Methode habe, die ein int zurückgibt , etwa getQuantity() in der Sugar- Klasse , dann könnte die Methode 0 zurückgeben , wenn das Ergebnis null ist , um „keine Menge“ darzustellen. Wenn wir dies wissen, können wir davon ausgehen, dass der Sugar- Parameter in der Coffee- Klasse als optional dargestellt werden kann. Auf den ersten Blick scheint dies eine gute Idee zu sein, da Zucker theoretisch nicht unbedingt im Kaffee enthalten sein muss. An dieser Stelle möchte ich jedoch darauf eingehen, wann Optional nicht verwendet werden sollte. Wir sollten die Verwendung von Optional in den folgenden Szenarien vermeiden:
  • Als Parametertypen für POJOs , beispielsweise DTOs . Optionale Optionen sind nicht serialisierbar. Wenn Sie sie also in einem POJO verwenden, wird das Objekt unseresialisierbar.

  • Als Methodenargument. Wenn ein Methodenargument null sein kann, ist die Übergabe von null aus reiner Codeperspektive der Übergabe von Optional immer noch vorzuziehen. Darüber hinaus können Sie überladene Methoden erstellen, um das Fehlen eines Null-Methodenarguments abstrakt zu behandeln.

  • Zur Darstellung eines fehlenden Collection-Objekts. Sammlungen können leer sein, daher muss eine leere Sammlung wie ein leeres Set oder eine leere Liste verwendet werden, um eine Sammlung ohne Werte darzustellen.

Abschluss

Optional ist zu einer leistungsstarken Ergänzung der Java-Bibliothek geworden. Es bietet eine Möglichkeit, mit Objekten umzugehen, die möglicherweise nicht vorhanden sind. Daher sollte es bei der Entwicklung von Methoden berücksichtigt werden, ohne in die Missbrauchsfalle zu tappen. Ja, Sie können großartigen Code schreiben, der Nullprüfungen und Nullbehandlung implementiert, aber die Java-Community bevorzugt die Verwendung von Optional. Es vermittelt effektiv, wie mit fehlenden Werten umgegangen wird, ist viel einfacher zu lesen als umständliche Nullprüfungen und führt auf lange Sicht zu weniger Fehlern in Ihrem Code.
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION