Perché utilizzare Optional.of over Optional.ofNullable?


232

Quando si utilizza la Optionalclasse Java 8 , ci sono due modi in cui un valore può essere racchiuso in un facoltativo.

String foobar = <value or null>;
Optional.of(foobar);         // May throw NullPointerException
Optional.ofNullable(foobar); // Safe from NullPointerException

Capisco Optional.ofNullableè l'unico modo sicuro di utilizzare Optional, ma perché Optional.ofesiste affatto? Perché non semplicemente usare Optional.ofNullable ed essere sempre al sicuro?


1
per favore dimmi quale pacchetto deve importare per usare questo?
LoveToCode

4
@LoveToCode java.util.Optional- È disponibile se si utilizza JDK 8 o versioni successive
whirlwin

11
Mi piacerebbe se avessero ofNullable()chiamato of()e of()nominatoofNotNull()
Robert Niestroj il

Si prega di fare riferimento a baeldung.com/java-optional
TG

Come ti stai chiedendo "perché esiste Optional.of? Perché non usare Optional.ofNullable ed essere sempre al sicuro?" Diciamo che se i dati richiesti dall'utente non sono presenti, allora dobbiamo gettare un'eccezione. Quindi, dipende totalmente dal tuo caso d'uso. baeldung.com/java-optional-throw-exception
Karan Arora

Risposte:


306

La tua domanda si basa sul presupposto che il codice che può essere lanciato NullPointerExceptionè peggiore del codice che potrebbe non esserlo. Questa ipotesi è sbagliata. Se ti aspetti che il tuo foobarnon sia mai nullo a causa della logica del programma, è molto meglio usare Optional.of(foobar)come vedrai un NullPointerExceptionche indicherà che il tuo programma ha un bug. Se si utilizza Optional.ofNullable(foobar)e ciò foobaraccade a nullcausa del bug, il programma continuerà silenziosamente a funzionare in modo errato, il che potrebbe essere un disastro più grande. In questo modo un errore può verificarsi molto più tardi e sarebbe molto più difficile capire a che punto è andato storto.


129
" Se ti aspetti che il tuo foobar non sia mai nullo a causa della logica del programma, è molto meglio usarloOptional.of(foobar) ". Questo sembra un po 'strano - quando sappiamo che il valore non sarà nullin ogni caso, allora perché non usare il valore stesso, invece di racchiuderlo in un Optional?
Konstantin Yovkov,

54
@kocko, potresti dover restituire il Optionalmetodo dal metodo richiesto dall'interfaccia che stai implementando (probabilmente altri implementatori potrebbero restituire un facoltativo vuoto). Oppure vuoi creare una raccolta / flusso di optionals, alcuni dei quali sono garantiti non nulli e altri no. Oppure hai una logica condizionale che crea un facoltativo in diversi rami e in un singolo ramo sei sicuro che sia non nullo.
Tagir Valeev,

28
Perché Opzionale significa che può essere presente o assente. Assente! = Null. nullin questo caso significa "Mi aspetto che sia presente il foobar, ma a causa di un bug è nullo". Optional.isPresent() == falsesignifica che il foobar non è presente, vale a dire questo è previsto, un comportamento legittimo.
Buurman,

43
@kocko: semplice esempio: return list.isEmpty()? Optional.empty(): Optional.of(list.get(0));la listsi prevede di non contenere nulli valori ...
Holger

5
@Harish se mi stai chiedendo, non consiglio di usare Optionals ovunque. Questa è una domanda separata. Puoi controllare alcune opinioni qui .
Tagir Valeev,

12

Inoltre, se sai che il tuo codice non dovrebbe funzionare se l'oggetto è null, puoi generare un'eccezione usando Optional.orElseThrow

String nullName = null;
String name = Optional.ofNullable(nullName).orElseThrow(NullPointerException::new);

1
Ma per questo, puoi usare anche il più cortoString name = Objects.requireNonNull(nullName);
Holger

1
Buon punto @Holger, tuttavia il metodo .orElse () consente eccezioni personalizzate che potrebbero aiutarti a gestire meglio il flusso di controllo o la registrazione delle informazioni.
Nikos Stais,

1
Bene, puoi fornire un messaggio per l'eccezione per fornire ulteriori informazioni. Qualsiasi altro tentativo di personalizzazione, come l'utilizzo di un'eccezione diversa rispetto a NullPointerExceptionquando il problema è chiaramente un riferimento che è nullmentre non dovrebbe, sarebbe un passo nella direzione sbagliata.
Holger,

inoltre, puoi usare Opzionale per lanciare un'eccezione più specifica (ad esempio personalizzata), non NPE, NPE è troppo generico, puoi lanciare qualcosa del generenew NullNameException("meaningful msg")
Dáve

1

Questo dipende dagli scenari.

Supponiamo che tu abbia alcune funzionalità aziendali e che tu debba elaborare ulteriormente qualcosa con quel valore, ma avere un nullvalore al momento dell'elaborazione lo influenzerebbe.

Quindi, in tal caso, è possibile utilizzare Optional<?>.

String nullName = null;

String name = Optional.ofNullable(nullName)
                      .map(<doSomething>)
                      .orElse("Default value in case of null");

0

Opzionale dovrebbe essere utilizzato principalmente per i risultati dei Servizi comunque. Nel servizio sai cosa hai a portata di mano e restituisci Optional.of (someValue) se hai un risultato e restituisci Optional.empty () se non lo fai. In questo caso, un valore non dovrebbe mai essere nullo e comunque, si restituisce un Opzionale.


1
Grazie per la modifica del Sumesh, ma il "someValue" nell'ultima riga che hai modificato per essere "some Value", fa riferimento alla variabile in "Optional.of (someValue)" sopra e dovrebbe rimanere someValue, credo.
espendennis,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.