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 .
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 .
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.
GO TO FULL VERSION