2016-12-16 16 views
4

Ich habe here lesen, warum Optional.of() sollte über Optional.ofNullable() verwendet werden, aber die Antwort befriedigte mich nicht, so frage ich etwas anders:Gibt es einen wirklichen Grund, Optional.of() zu verwenden?

Wenn Sie sicher sind, dass Ihre Methode nicht null zurückkehrt, warum sollte benutzen Sie überhaupt Optional? Soweit ich weiß, besteht der mehr oder weniger einzige Zweck darin, den "Benutzer einer Methode" daran zu erinnern, dass er sich möglicherweise mit null-Werten befassen muss. Wenn er sich nicht mit null-Werten befassen muss, warum sollte er mit einer Optional gestört werden?

Ich frage, weil ich vor kurzem meine Service-Schicht Optionals anstelle von Nullen (in bestimmten Situationen) zurückgegeben habe. Ich benutzte Optional.of() und war sehr verwirrt, als es einen NullPointer warf.

Eine Probe von dem, was ich getan habe:

Optional valueFromDB = getUserById("12"); 
User user = valueFromDB.get(); 

..... 

public Optional<User> getUserById(String id) { 
    //... 
    return Optional.of(userRepository.findOne(id)); // NullPointerException! 
} 

Wenn null nicht möglich ist, sehe ich nicht, warum man es in einem Optional wickeln würde. Der Typ in der verknüpften Antwort sagte: "Nun, wenn ein NullPointer passiert, passiert es sofort!" Aber will ich das wirklich? Wenn der einzige Zweck eines Optional ist, den Programmierer zu erinnern, der solch ein Objekt erhält, um null im Gedächtnis zu behalten (er HAT es auszupacken), warum sollte ich NullPointerException zur Verpackungszeit haben wollen?


Edit: Ich brauchte die Frage zu bearbeiten, weil es als Duplikat markiert habe, obwohl ich bereits gesagt, verknüpft Frage von Anfang an. Ich habe auch erklärt, warum die Antwort mich nicht befriedigt hat, aber jetzt muss ich meinen Text mit einer Erklärung bearbeiten. Aber hier ist ein Anhang zu dem, was ich fragen will, da ich 5 Antworten bekam und alle Antworten einen anderen Fall, aber nicht vollständig abgedeckt, was ich versuche, hier zu fragen:

Gibt es einen Grund, dass Optional.of (null) ist unmöglich und sie fügten speziell Optional.ofNullable() für den Nullfall hinzu?

Verwendung von Streams sollte nicht das Problem mit meiner Idee der Implementierung sein. Ich habe eine Menge Einblick aus Ihren Antworten, danke dafür. Aber die eigentliche Frage ist bis jetzt nicht beantwortet worden, soweit ich es verstehe/verstehe. Vielleicht hätte ich fragen sollen: "Was, wenn wir die Optional.of() Methode entfernen und nur Optional.ofNullable() in Java 9 zulassen, würde es ein Problem geben außer der Abwärtskompatibilität?"

+4

Der einzige Zweck von 'Optional' besteht darin, deutlich anzuzeigen, dass möglicherweise kein Ergebnis vorliegt. Bei richtiger Verwendung müssen Sie keine "Null" -Kontrollen durchführen und "user.ifPresent" (doAMethod()) 'ausführen oder in Streams und anderen JDK8-APIs verwenden, ohne nach" null "-Elementen suchen zu müssen. Wenn es richtig verwendet wird, kann es den Umfang der Nullprüfung in Ihrem Code reduzieren. –

+0

@M.Deinum: 'ifPresent' ist im Grunde ein Null-Check. : P Es sieht einfach besser aus und ist bequemer zu benutzen. Ich verstehe zwar die Sache mit den Streams, aber das hat nichts mit der Frage selbst zu tun. Ich habe Optionals nicht in Frage gestellt, ich habe gefragt, ob 'Optional.of()' nützlich ist. Tut mir leid, wenn das nicht klar war. – codepleb

+0

Wenn Ihre Methode nicht Null zurückgeben soll, stimme ich zu, dass Sie keine 'Optional' zurückgeben wollen. Auf der anderen Seite möchten Sie informiert werden, wenn der Wert, den Sie zurückgeben wollen, eines Tages null ist. Ich würde dafür eine gute alte Aussage verwenden. –

Antwort

1

Ich denke, Sie haben Recht mit Ihrer Meinung, dass Sie nicht optional verwenden sollten, wenn Sie sicher sind, dass Sie immer einen Rückgabewert haben.

Aber Ihre Methode ist nicht sicher, dass es immer einen Wert zurückgibt!

Denken Sie an einen Anruf an getUserById (-1). Es gibt (normalerweise) keinen Benutzer mit dieser ID, und Ihr userRepository wird null zurückgeben.

In diesem Fall sollten Sie Optional.ofNullable verwenden.

https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#ofNullable-T-

+2

Ja, aber die Frage ist, warum 'Optional.of()' überhaupt existiert. – codepleb

6

Sie mischen das API-Design Rationale mit Wissen innerhalb eines bestimmten Implementierung Code auf. Es ist durchaus möglich, dass eine Methode deklariert, eine Optional zurückzugeben, da der Wert möglicherweise nicht vorhanden ist, während an einer bestimmten Codestelle in der Methode bekannt ist, dass sie definitiv vorhanden ist. I.e.

String content; 
public Optional<String> firstMatch(String pattern) { 
    Matcher m = Pattern.compile(pattern).matcher(content); 
    return m.find()? Optional.of(m.group()): Optional.empty(); 
} 

Diese Rückgabetyp der Methode bezeichnet ein String, die nicht vorhanden sein könnte, während bei den Codestellen eine Optional Instanz erstellen, ist es bekannt, ob der Wert vorhanden ist oder fehlt. Es geht hier nicht darum, einen null Wert zu erkennen.

Ebenso innerhalb der Stream-API-Methoden findFirst() und findAny(), wird es an einer Stelle bekannt sein, ob ein Anpassungselement ist, wohingegen die Umwandlung ihrer Anwesenheit Abwesenheit bei einem passenden null Abstützelement ist ausdrücklich nicht unterstützt und soll eine NullPointerException, per specification auslösen. Daher wird Optional.of verwendet werden, um das Anpassungselement zurückzukehren, die Sie leicht in der Stack-Trace erkennen können, wenn Stream.of((Object)null) .findAny(); mit

+1

Siehe [hier] (http://stackoverflow.com/questions/31696485/why-use-optional-of-over-option-ofnullable#comment51344170_31696584) für ein anderes Beispiel ... – Holger

1

Angelika Langer sagt, dass Optional.ofNullable ist nur ein Convenience-Methode, die anderen beiden statischen Methoden von Optional aufrufen. Es ist implementiert als:

return value == null ? empty() : of(value) ; 

Auch sagt sie, dass Optional.ofNullable wurde in letzter Zeit an die API hinzugefügt.

Hier ist ihr Text in Deutsch Sprache: http://www.angelikalanger.com/Articles/EffectiveJava/80.Java8.Optional-Result/80.Java8.Optional-Result.html

So würde ich Optional.of nur verwenden, wenn null ein Fehler ist, die früh gefunden werden sollte. Dies ist, was Tagir Valeev sagte in: Why use Optional.of over Optional.ofNullable?

+0

@ OleV.V. Vielen Dank. Das habe ich korrigiert. –

3

Der andere Grund Optional.of(value) zu verwenden, wenn Sie wissen, dass value nicht null sein kann, ist, dass, wenn Sie auf dieser Optional zusätzliche Filteroperationen zu tun.

Zum Beispiel:

public static long getPageSizeFrom(HttpServletRequest request) { 
    return Optional.of(request.getParameter("pageSize")) 
        .filter(StringUtils::isNumeric) 
        .map(Long::valueOf) 
        .filter(page::hasPageSize) 
        .orElse(page::getDefaultPageSize) 
} 
1

Optional ist eines jener Dinge, die aus funktionalen Programmiersprachen und kippte in den Schoß von OO und prozeduralen Programmierer without muchbackground explanation importiert wurde ... die viel Schmerz und Hand verursacht hat wringen.

Zuerst wird eine schnelle Verbindung zu einer Blog-Post (nicht von mir), die stark die Luft auf diese löschen hilft: The Design of Optional

Optional ist wie Haskell Maybe zu funktionaler Programmierung Typen zusammen. Aufgrund der Art, wie starke Typisierung in der funktionalen Programmierung funktioniert, würde ein Programmierer in dieser Sprache Maybe verwenden, um zu sagen, dass ein Wert entweder Etwas oder Nichts sein kann. Das Etwas und Nichts sind eigentlich verschiedene Arten, hier. Alles, was die Werte in einem möglicherweise hat, um beide zu behandeln - der Code wird einfach nicht kompilieren, wenn es nicht beide behandelt.

Vergleichen Sie dieses Szenario mit der typischen Situation in C-basierten objektorientierten Sprachen (Java, C#, C++ usw.), in denen ein Objekt entweder einen Wert haben oder null sein kann. Wenn eine Methode mit Nullparametern als Edge-Fall umgehen muss, müssen Sie diesen Code explizit schreiben - und die faulen Programmierer, die wir alle sind, ist es genauso oft, wie wir es nicht tun.

Stellen Sie sich vor, welche Codierung wäre, wenn Code nicht kompiliert würde, es sei denn, Nullfälle wurden immer explizit behandelt. Das ist ein ziemlich enger Vergleich mit dem, was passiert, wenn Maybe in funktionalen Sprachen verwendet wird.

Wenn wir Sprachfunktionen aus der funktionalen Programmierung übernehmen, und der Compiler verhält sich so, wie er immer ist, und wir codieren die Art, wie wir es immer haben ... Sie können sehen, dass eine Trennung stattfindet.

Separat kann Optional als einfacher Ersatz für Null verwendet werden. Weil es so vertraut erscheint und neu ist, neigen magpie developers dazu, es als Ersatz für Situationen zu verwenden, in denen zuvor Null-Checks stattgefunden hätten. Aber am Ende ist foo.isPresent() wirklich so anders als foo! = Null. Wenn das der einzige Unterschied ist, ist es sinnlos.

Und noch nicht einmal, wie Optional kann ein Stand-in für Autoboxing und Unboxing in Java sein.

Jetzt zurück zu Ihrer spezifischen Frage über die bestimmte API von Optional in Java, Vergleich von Nullable() vs. von(), das Beste, was ich herausfinden kann, ist, dass Sie voraussichtlich nicht diejenigen in typischen verwenden Code. Sie werden hauptsächlich am Ende der stream() Operationen verwendet. Sie können den Code zu Optional.of() vs. Optional.ofNullable() anzeigen und sehen Sie selbst, dass der einzige Unterschied ist, dassNullable überprüft, ob der Wert null ist und Dinge für diese Situation anordnet.

Mein abgestumpftes Auge sieht nicht viel Nutzen für die Verwendung von Optional in Java, es sei denn, ich verwende Java 8-Streams und ich muss. Some würde sagen, dass der Hauptvorteil der Verwendung von Optional als Typ für Nicht-Stream-Verwendung darin besteht, anzugeben, dass ein bestimmter Parameter optional ist - das heißt, die Logik nimmt eine andere Route, wenn sie da ist und nicht dort. Was wiederum mit null möglich ist. Aber ich würde sagen, dass das mit Optional verbundene mentale Gepäck bedeutet, dass Sie für jeden weiteren Schritt des angeblich ausführlicheren Codes mehrere Schritte rückwärts machen, indem Sie die Leute dazu bringen zu verstehen, dass das Optional (in diesem speziellen Fall) fast ausschließlich kosmetischer Natur ist. Für die beschriebene Situation würde ich wahrscheinlich auf Nullen und Null-Checks zurückgreifen.

+0

Danke für deine ehrliche Meinung.Der größte Grund, sie zu benutzen, ist, um die Entwickler daran zu erinnern, dass ein Wert null sein könnte. Statische Code-Analyse kann grundsätzlich dasselbe tun. – codepleb

Verwandte Themen