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 clonemetodo Enumgarantisce che le enumcostanti 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 enumtipo oltre a quelle definite dalle enumcostanti.
Poiché esiste solo un'istanza di ogni enumcostante, è possibile utilizzare l' ==operatore al posto del equalsmetodo quando si confrontano due riferimenti a oggetti se è noto che almeno uno di essi fa riferimento a una enumcostante . (Il equalsmetodo in Enumè un finalmetodo che si limita a invocare super.equalsil 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 enumsono:
- Funziona.
- È più veloce.
- È più sicuro in fase di esecuzione.
- È più sicuro in fase di compilazione.