Sono in ritardo al gioco, ma per quello che vale, voglio aggiungere i miei 2 centesimi. Sono contrari all'obiettivo progettuale diOptional
, che è ben riassunto dalla risposta di Stuart Marks , ma sono ancora convinto della loro validità (ovviamente).
Usa facoltativo ovunque
In generale
Ho scritto un intero post sul blog sull'utilizzo,Optional
ma sostanzialmente si riduce a questo:
- progettare le lezioni per evitare opzionalità ove possibile
- in tutti i restanti casi, l'impostazione predefinita dovrebbe essere quella di utilizzare
Optional
invece dinull
- eventualmente fare eccezioni per:
- variabili locali
- restituisce valori e argomenti a metodi privati
- blocchi di codice critici per le prestazioni (nessuna ipotesi, utilizzare un profiler)
Le prime due eccezioni possono ridurre il sovraccarico percepito dei riferimenti a capo e a capo Optional
. Sono scelti in modo tale che un null non possa mai legalmente passare un confine da un'istanza all'altra.
Si noti che ciò non consentirà quasi mai di accedere Optional
alle raccolte, il che è quasi negativo quanto le null
. Basta non farlo. ;)
Per quanto riguarda le tue domande
- Sì.
- Se il sovraccarico non è un'opzione, sì.
- Se altri approcci (sottoclasse, decorazione, ...) non sono un'opzione, sì.
- Per favore no!
vantaggi
In questo modo si riduce la presenza di null
s nella base di codice, sebbene non li sradichi. Ma questo non è nemmeno il punto principale. Ci sono altri importanti vantaggi:
Chiarisce l'intento
utilizzando Optional
indica chiaramente che la variabile è, beh, facoltativa. Qualsiasi lettore del tuo codice o consumatore della tua API sarà picchiato in testa per il fatto che potrebbe non esserci nulla e che è necessario un controllo prima di accedere al valore.
Rimuove l'incertezza
Senza Optional
il significato di un null
evento non è chiaro. Potrebbe essere una rappresentazione legale di uno stato (vedi Map.get
) o un errore di implementazione come un'inizializzazione mancante o non riuscita.
Questo cambia radicalmente con l'uso persistente di Optional
. Qui, già l'occorrenza di null
significa la presenza di un bug. (Perché se il valore fosse lasciato mancare, ne Optional
sarebbe stato usato uno.) Questo rende molto più semplice il debug di un'eccezione puntatore null poiché la domanda sul significato di questo null
è già stata risolta.
Più controlli null
Ora che nulla può null
più essere , questo può essere applicato ovunque. Sia con annotazioni, asserzioni o semplici verifiche, non devi mai pensare se questo argomento o quel tipo di ritorno possono essere nulli. Non può!
svantaggi
Certo, non esiste un proiettile d'argento ...
Prestazione
L'avvolgimento di valori (soprattutto primitivi) in un'istanza aggiuntiva può ridurre le prestazioni. In anelli stretti questo potrebbe diventare evidente o anche peggio.
Si noti che il compilatore potrebbe essere in grado di aggirare il riferimento aggiuntivo per le brevi vite di Optional
s. In Java 10 tipi di valore potrebbero ulteriormente ridurre o rimuovere la penalità.
serializzazione
Optional
non è serializzabile ma una soluzione alternativa non è eccessivamente complicata.
invarianza
A causa dell'invarianza dei tipi generici in Java, alcune operazioni diventano ingombranti quando il tipo di valore effettivo viene inserito in un argomento di tipo generico. Qui viene fornito un esempio (vedi "Polimorfismo parametrico") .
Map<Character, String>
. Se non v'è alcuna sostituzione posso usare questo:Optional.ofNullable(map.get(c)).orElse(String.valueOf(c))
. Si noti inoltre che Opzionale è stato rubato dalla Guava e ha una sintassi molto più bella:Optional.fromNullable(map.get(c)).or(String.valueOf(c));