Nehmen Sie die beiden Codebeispiele:
if(optional.isPresent()) {
//do your thing
}
if(variable != null) {
//do your thing
}
Soweit ich das beurteilen kann, besteht der offensichtlichste Unterschied darin, dass für das optionale Objekt ein zusätzliches Objekt erstellt werden muss.
Viele Menschen haben jedoch schnell begonnen, Optionals einzuführen. Was ist der Vorteil der Verwendung von Optionen gegenüber einer Nullprüfung?
if
Aussagen im letzten Jahrzehnt soooooooooooooooooooooo soooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooif(x.isPresent) fails_on_null(x.get)
Sie das Typensystem verlassen und die Garantie behalten müssen, dass der Code über die (zugegebenermaßen kurze) Distanz zwischen der Bedingung und dem Funktionsaufruf nicht "in Ihrem Kopf" zerbricht. Imoptional.ifPresent(fails_on_null)
Typensystem macht sich diese Garantie für Sie bezahlt, und Sie müssen sich keine Sorgen machen.Optional.ifPresent
(und verschiedenen anderen Java-Konstrukten) besteht darin, dass Sie nur endgültige Variablen effektiv ändern und keine geprüften Ausnahmen auslösen können. Grund genugifPresent
, dies leider oft zu vermeiden .Antworten:
Optional
nutzt das Typensystem für die Arbeit, die Sie sonst in Ihrem Kopf erledigen müssten: Erinnern Sie sich, ob eine bestimmte Referenz vorhanden ist oder nichtnull
. Das ist gut. Es ist immer klug, den Compiler mit langweiliger Drogenarbeit umgehen zu lassen und menschliche Gedanken für kreative, interessante Arbeit zu reservieren.Ohne
Optional
ist jeder Verweis in Ihrem Code wie eine nicht explodierte Bombe. Der Zugriff darauf kann nützlich sein oder Ihr Programm mit einer Ausnahme beenden.Mit Optional und ohne
null
ist jeder Zugriff auf eine normale Referenz erfolgreich, und jede Referenz auf eine Option ist erfolgreich, sofern sie nicht deaktiviert ist und Sie dies nicht überprüft haben. Das ist ein enormer Gewinn an Wartbarkeit.Leider sind die meisten Sprachen, die jetzt angeboten
Optional
werden, nicht abgeschafft wordennull
. Sie können also nur von dem Konzept profitieren, indem Sie eine strikte Politik des "absolut Neinnull
, niemals" einführen. Daher istOptional
Java beispielsweise nicht so überzeugend, wie es im Idealfall sein sollte.quelle
Optional
nur daran zu erinnern, dass der Wert null sein könnteEin
Optional
bringt stärkere Typisierung in Operationen , die fehlschlagen, da die anderen Antworten werden abgedeckt, aber das ist weit von der interessanteste oder wertvoller SacheOptionals
an den Tisch bringen. Viel nützlicher ist die Möglichkeit, die Überprüfung auf Fehler zu verzögern oder zu vermeiden und viele möglicherweise fehlgeschlagene Vorgänge auf einfache Weise zusammenzustellen.Überlegen Sie, ob Ihre
optional
Variable aus Ihrem Beispielcode stammt, und führen Sie zwei zusätzliche Schritte aus, bei denen jeder möglicherweise fehlschlägt. Wenn ein Schritt auf dem Weg fehlschlägt, möchten Sie stattdessen einen Standardwert zurückgeben. BeiOptionals
korrekter Verwendung erhalten Sie Folgendes:Bei
null
hätte ich dreimalnull
nachsehen müssen, bevor ich fortfahre, was dem Code eine Menge Komplexität und Wartungsprobleme hinzufügt.Optionals
habe diesen check in dieflatMap
undorElse
funktionen eingebaut .Hinweis Ich habe nicht
isPresent
einmal angerufen , was Sie bei der Verwendung als Code-Geruch betrachten solltenOptionals
. Das bedeutet nicht unbedingt, dass Sie niemals verwenden sollten, sondernisPresent
nur, dass Sie jeden Code, der dies tut, einer eingehenden Prüfung unterziehen sollten, um festzustellen, ob es einen besseren Weg gibt. Ansonsten haben Sie recht, Sie erhalten nur einen geringfügigen Sicherheitsvorteil gegenüber der Verwendungnull
.Beachten Sie auch, dass ich nicht so besorgt bin, dies alles in eine Funktion zu kapseln, um andere Teile meines Codes vor Nullzeigern vor Zwischenergebnissen zu schützen. Wenn es
.orElse(defaultValue)
zum Beispiel sinnvoller ist, meine in einer anderen Funktion zu haben, habe ich viel weniger Bedenken, sie dort abzulegen, und es ist viel einfacher, die Operationen nach Bedarf zwischen verschiedenen Funktionen zusammenzustellen.quelle
Es wird die Möglichkeit von Null als gültige Antwort hervorgehoben, von der häufig (zu Recht oder zu Unrecht) angenommen wird, dass sie nicht zurückgegeben wird. Durch das Hervorheben der wenigen Male, wenn Null gültig ist, wird vermieden, dass Ihr Code mit einer großen Anzahl sinnloser Nullprüfungen verunreinigt wird.
Idealerweise würde das Setzen einer Variablen auf Null irgendwo anders als optional zu einem Fehler bei der Kompilierung führen. Beseitigen von Laufzeit-Nullzeiger-Ausnahmen. Offensichtlich schließt die Abwärtskompatibilität dies leider aus
quelle
Lassen Sie mich Ihnen ein Beispiel geben:
Es ist ziemlich klar, wofür diese Methode gedacht ist. Aber was passiert, wenn das Repository keinen Benutzer mit der angegebenen ID enthält? Es könnte eine Ausnahme auslösen oder es gibt möglicherweise null zurück?
Zweites Beispiel:
Was passiert hier, wenn kein Benutzer mit der angegebenen ID vorhanden ist? Richtig, Sie erhalten die Instanz Optional.absent () und können sie mit Optional.isPresent () überprüfen. Die Methodensignatur mit Optional bezieht sich expliziter auf den Vertrag. Es ist sofort klar, wie sich die Methode verhalten soll.
Es hat auch einen Vorteil beim Lesen des Client-Codes:
Ich habe mein Auge darauf trainiert, .get () als sofortigen Codegeruch zu sehen. Dies bedeutet, dass der Client den Vertrag der aufgerufenen Methode absichtlich ignoriert. Dies ist viel einfacher zu sehen als ohne Optional, da Sie in diesem Fall nicht sofort wissen, welchen Vertrag die aufgerufene Methode hat (ob sie in ihrer Rückgabe null zulässt oder nicht), sodass Sie diese zuerst überprüfen müssen.
Optional wird mit der Konvention verwendet, dass Methoden mit dem Rückgabetyp Optional niemals null zurückgeben, und normalerweise auch mit der (weniger starken) Konvention, dass Methoden ohne den optionalen Rückgabetyp niemals null zurückgeben (es ist jedoch besser, sie mit @Nonnull, @NotNull oder ähnlich zu kommentieren). .
quelle
Ein
Optional<T>
erlaubt Ihnen, "Fehler" oder "kein Ergebnis" als gültigen Antwort- / Rückgabewert für Ihre Methoden zu haben (denken Sie zB an eine Datenbanksuche). Die Verwendung von anOptional
anstelle von,null
um einen Fehler anzuzeigen / kein Ergebnis hat einige Vorteile:null
eine Rückgabe möglich ist.null
sollte, zumindest meiner Meinung nach, nicht dazu verwendet werden, etwas anzuzeigen, da die Semantik möglicherweise nicht vollständig klar ist. Es sollte verwendet werden, um dem Garbage Collector mitzuteilen, dass das zuvor referenzierte Objekt gesammelt werden kann.Optional
Klasse bietet viele nützliche Methoden, um mit den Werten bedingt zu arbeiten (z. B.ifPresent()
) oder Standardwerte auf transparente Weise zu definieren (orElse()
).Leider muss
null
der Code nicht vollständig überprüft werden, da dasOptional
Objekt selbst möglicherweise noch vorhanden istnull
.quelle
Zusätzlich zu den anderen Antworten besteht der andere Hauptvorteil von Optionals beim Schreiben von sauberem Code darin, dass Sie einen Lambda-Ausdruck verwenden können, falls der Wert vorhanden ist, wie unten gezeigt:
quelle
Betrachten Sie die folgende Methode:
Schauen wir uns nun einen Aufrufcode an:
Dies führt zu einem möglicherweise schwer zu verfolgenden Absturz, da
dance
keine Null erwartet wurde.Dies führt zu einem Kompilierungsfehler, da dance ein
Person
nicht erwartet hatOptional<Person>
Wenn ich keine Person hatte, führt dies zu einer Ausnahme in dieser Zeile, an dem Punkt, an dem ich unrechtmäßig versucht habe, die
Optional<Person>
in eine Person umzuwandeln . Der Schlüssel ist, dass anders als bei der Übergabe einer Null die Spuren außer hier nicht an irgendeiner anderen Stelle im Programm sind.Zusammenfassend lässt sich sagen, dass die missbräuchliche Verwendung von optionalen Elementen das Auffinden von Problemen erleichtert.
quelle
Optional.get()
Ihres Codes Ausnahmen auslösen, ist Ihr Code schlecht geschrieben - Sie sollten fast nie Optional.get aufrufen, ohneOptional.isPresent()
vorher zu prüfen (wie im OP angegeben), oder Sie könnten schreibenoptionalPersion.ifPresent(myObj::dance)
.In Objective-C sind alle Objektreferenzen optional. Aus diesem Grund ist Code wie Sie dumm.
Code wie der obige ist in Objective-C unbekannt. Stattdessen würde der Programmierer einfach:
Wenn
variable
ein Wert enthalten ist,doThing
wird er aufgerufen. Wenn nicht, kein Schaden. Das Programm behandelt es als No-Op und läuft weiter.Dies ist der eigentliche Vorteil von Optionals. Sie müssen Ihren Code nicht mit verunreinigen
if (obj != nil)
.quelle
Das offensichtliche Problem hier ist , dass , wenn „optional“ wirklich ist , fehlt (dh null ist) , dann Ihr Code mit einer Nullreferenceexception sprengen wird (oder ähnlich) versucht , auf einer Null - Objekt Referenz jede Methode zu nennen!
Möglicherweise möchten Sie eine statische Helper-Klassenmethode schreiben, mit der die Nullheit eines bestimmten Objekttyps wie folgt bestimmt wird:
oder vielleicht sinnvoller:
Aber sind beide wirklich lesbarer / verständlicher / wartbarer als das Original?
quelle