Ich habe kürzlich darüber gelesen und Leute gesehen, die diese Klasse verwenden, aber in fast allen Fällen null
hätte die Verwendung auch funktioniert - wenn nicht intuitiver. Kann jemand ein konkretes Beispiel geben, wo Optional
etwas erreicht werden null
könnte, das nicht oder viel sauberer wäre? Das einzige, woran ich denken kann, ist, es damit zu verwenden, Maps
dass keine null
Schlüssel akzeptiert werden , aber selbst das könnte mit einer seitlichen "Zuordnung" des Nullwerts geschehen. Kann mir jemand ein überzeugenderes Argument liefern? Danke dir.
89
Antworten:
Guave Teammitglied hier.
Der wahrscheinlich größte Nachteil
null
ist, dass es nicht offensichtlich ist, was es in einem bestimmten Kontext bedeuten sollte: Es hat keinen illustrativen Namen. Es ist nicht immer offensichtlich, dassnull
dies "kein Wert für diesen Parameter" bedeutet - zum Teufel, als Rückgabewert bedeutet es manchmal "Fehler" oder sogar "Erfolg" (!!) oder einfach "die richtige Antwort ist nichts".Optional
ist häufig das Konzept, das Sie tatsächlich meinen, wenn Sie eine Variable auf Null setzen, aber nicht immer. Wenn dies nicht der Fall ist, empfehlen wir Ihnen, eine eigene Klasse zu schreiben, ähnlich wie,Optional
jedoch mit einem anderen Namensschema, um zu verdeutlichen, was Sie tatsächlich meinen.Aber ich würde sagen, der größte Vorteil
Optional
liegt nicht in der Lesbarkeit: Der Vorteil ist die Idiotensicherheit. Es zwingt Sie, aktiv über den fehlenden Fall nachzudenken, wenn Sie möchten, dass Ihr Programm überhaupt kompiliert wird, da Sie denOptional
Fall aktiv auspacken und ansprechen müssen. Null macht es beunruhigend einfach, Dinge einfach zu vergessen, und obwohl FindBugs hilft, denke ich, dass es das Problem nicht annähernd so gut angeht. Dies ist besonders relevant, wenn Sie Werte zurückgeben, die möglicherweise "vorhanden" sind oder nicht. Es ist weitaus wahrscheinlicher, dass Sie (und andere) vergessen, dassother.method(a, b)
einnull
Werta
zurückgegeben werden könnte,null
als dass Sie dies bei der Implementierung vergessen könntenother.method
. RückkehrOptional
macht es Anrufern unmöglich, diesen Fall zu vergessen, da sie das Objekt selbst auspacken müssen.Aus diesen Gründen empfehlen wir, dass Sie
Optional
als Rückgabetyp für Ihre Methoden verwenden, jedoch nicht unbedingt in Ihren Methodenargumenten.(Dies ist übrigens völlig aus der Diskussion hier gestrichen .)
quelle
Map
Erträge ,null
wenn ein Schlüssel ist , nicht zugeordnete, aber erinnern , dass , wenn Sie das tunmap.put(key, null)
, dannmap.containsKey(key)
zurückkehren wird ,true
abermap.get(key)
wird zurückkehrennull
.Optional
kann nützlich sein, um die Unterscheidung zwischen dem Fall "explizit auf Null abgebildet" und dem Fall "Nicht in der Karte vorhanden" zu klären. Ich gebe zu, dassOptional
dies missbraucht werden kann, aber ich bin noch nicht davon überzeugt, dass der von Ihnen beschriebene Fall ein Missbrauch ist.Optional<T>
ist das der Wert "gefunden, aber nicht gültig". Oder genauer gesagt,Optional<T>
ist eine Art und Weise zu schmücken jede ArtT
mit einem zusätzlichen „gefunden, aber nicht gültig“ Wert - eine neue Art zu schaffen , durch die Kombination von zwei vorhandenen Typen. Wenn Sie hundert Klassen haben, kann es schwierig werden, für jede Klasse einen eigenen "gefundenen, aber nicht gültigen" Wert zu erstellen, der jedochOptional<T>
für alle problemlos funktioniert.Es sieht wirklich aus wie das
Maybe
Monadenmuster von Haskell.Sie sollten Folgendes lesen, Wikipedia Monad (funktionale Programmierung) :
Und lesen Von Optional zu Monad mit Guava auf Blog Kerflyn ist, die diskutiert über die Fakultativ von Guava als Monade verwendet:
Bearbeiten: Mit Java8 gibt es eine integrierte Option, die monadische Operatoren wie hat
flatMap
. Dies war ein kontroverses Thema, wurde aber schließlich umgesetzt.Siehe http://www.nurkiewicz.com/2013/08/optional-in-java-8-cheat-sheet.html
Der
flatMap
Bediener ist wichtig, um monadische Operationen zuzulassen, und ermöglicht das einfache Verketten von Anrufen, die alle optionale Ergebnisse zurückgeben.Denken Sie darüber nach, wenn Sie den
map
Operator 5 Mal verwendet haben, erhalten Sie einenOptional<Optional<Optional<Optional<Optional<String>>>>>
, währendflatMap
Sie ihn verwendenOptional<String>
Seit Java8 würde ich Guavas Optional, das weniger leistungsfähig ist, lieber nicht verwenden.
quelle
Ein guter Grund, es zu verwenden, ist, dass es Ihre Nullen sehr aussagekräftig macht. Anstatt eine Null zurückzugeben, die viele Dinge bedeuten könnte (wie Fehler oder Misserfolg oder leer usw.), können Sie Ihrer Null einen 'Namen' geben. Schauen Sie sich dieses Beispiel an:
Definieren wir ein grundlegendes POJO:
}}
Nutzen wir nun dieses einfache POJO:
Vermeiden wir jetzt die Verwendung von null und führen Sie unsere Überprüfungen mit Optional durch, damit dies sinnvoll ist
Somit ist es am Ende eine Möglichkeit, Nullen sinnvoll und weniger mehrdeutig zu machen.
quelle
Der wichtigste Vorteil von Optional besteht darin, dass dem Vertrag zwischen dem Implementierer und dem Aufrufer einer Funktion weitere Details hinzugefügt werden. Aus diesem Grund ist sowohl für Parameter als auch für den Rückgabetyp nützlich.
Wenn Sie die Konvention so gestalten, dass sie immer
Optional
mögliche Nullobjekte enthält, fügen Sie Fälle wie:Optional<Integer> maxPrime(Optional<Integer> from, Optional<Integer> to)
Der Vertrag hier legt klar fest, dass die Möglichkeit besteht, dass ein Ergebnis nicht zurückgegeben wird, zeigt aber auch, dass es mit
from
undto
als abwesend funktioniert .Optional<Integer> maxPrime(Optional<Integer> from, Integer to)
Der Vertrag legt fest, dass das von optional ist, sodass ein fehlender Wert eine besondere Bedeutung haben kann, z. B. ab 2. Ich kann davon ausgehen, dass ein Nullwert für den
to
Parameter eine Ausnahme auslöst.Der gute Teil der Verwendung von Optional besteht darin, dass der Vertrag sowohl beschreibend (ähnlich wie bei
@NotNull
Anmerkungen) als auch formal wurde, da Sie Code schreiben müssen, um.get()
damit fertig zu werdenOptional
.quelle