Può ==
essere usato su enum
?
Sì: gli enum hanno controlli di istanza precisi che ti consentono ==
di confrontare le istanze. Ecco la garanzia fornita dalla specifica della lingua (enfasi da me):
Un tipo enum non ha istanze diverse da quelle definite dalle sue costanti enum.
È un errore in fase di compilazione tentare di creare un'istanza esplicita di un tipo enum. Il final clone
metodo Enum
garantisce che le enum
costanti non possano mai essere clonate e il trattamento speciale con il meccanismo di serializzazione garantisce che istanze duplicate non vengano mai create a causa della deserializzazione. È vietata l'istanza riflessiva dei tipi di enum. Insieme, queste quattro cose assicurano che non esistano istanze di un enum
tipo oltre a quelle definite dalle enum
costanti.
Poiché esiste solo un'istanza di ogni enum
costante, è possibile utilizzare l' ==
operatore al posto del equals
metodo quando si confrontano due riferimenti a oggetti se è noto che almeno uno di essi fa riferimento a una enum
costante . (Il equals
metodo in Enum
è un final
metodo che si limita a invocare super.equals
il suo argomento e restituisce il risultato, eseguendo così un confronto di identità.)
Questa garanzia è abbastanza forte che Josh Bloch consiglia, se insisti nell'usare il modello singleton, il modo migliore per implementarlo è usare un singolo elemento enum
(vedi: Effective Java 2nd Edition, Item 3: Enforce the singleton property with a costruttore privato o un tipo enum ; anche sicurezza thread in Singleton )
Quali sono le differenze tra ==
e equals
?
Come promemoria, va detto che generalmente ==
NON è una valida alternativa a equals
. Quando lo è, tuttavia (come con enum
), ci sono due importanti differenze da considerare:
==
non lancia mai NullPointerException
enum Color { BLACK, WHITE };
Color nothing = null;
if (nothing == Color.BLACK); // runs fine
if (nothing.equals(Color.BLACK)); // throws NullPointerException
==
è soggetto al controllo di compatibilità del tipo al momento della compilazione
enum Color { BLACK, WHITE };
enum Chiral { LEFT, RIGHT };
if (Color.BLACK.equals(Chiral.LEFT)); // compiles fine
if (Color.BLACK == Chiral.LEFT); // DOESN'T COMPILE!!! Incompatible types!
Dovrebbe ==
essere usato quando applicabile?
Bloch menziona specificamente che le classi immutabili che hanno il controllo adeguato sulle loro istanze possono garantire ai loro clienti che ==
è utilizzabile. enum
è specificamente menzionato per esemplificare.
Articolo 1: considerare i metodi di fabbrica statici anziché i costruttori
[...] consente a una classe immutabile di garantire che non esistono due istanze uguali: a.equals(b)
se e solo se a==b
. Se una classe offre questa garanzia, i suoi clienti possono utilizzare l' ==
operatore invece del equals(Object)
metodo, il che può comportare un miglioramento delle prestazioni. I tipi Enum forniscono questa garanzia.
Per riassumere, gli argomenti per l'utilizzo di ==
on enum
sono:
- Funziona.
- È più veloce.
- È più sicuro in fase di esecuzione.
- È più sicuro in fase di compilazione.