Może ==
być używany na enum
?
Tak: wyliczenia mają ścisłą kontrolę instancji, która umożliwia ==
porównywanie instancji. Oto gwarancja zawarta w specyfikacji języka (moje wyróżnienie):
Typ wyliczeniowy nie ma innych wystąpień niż te zdefiniowane przez jego stałe wyliczeniowe.
Błędem podczas kompilacji jest próba jawnego utworzenia wystąpienia typu wyliczeniowego. Ta final clone
metoda Enum
zapewnia, że enum
stałe nigdy nie będą klonowane, a specjalne traktowanie przez mechanizm serializacji gwarantuje, że w wyniku deserializacji nigdy nie zostaną utworzone zduplikowane instancje. Instancja refleksyjna typów wyliczeniowych jest zabroniona. Razem te cztery rzeczy zapewniają, że nie enum
istnieją żadne instancje typu poza tymi zdefiniowanymi przez enum
stałe.
Ponieważ istnieje tylko jedna instancja każdej enum
stałej, dopuszczalne jest użycie ==
operatora zamiast equals
metody podczas porównywania dwóch odniesień do obiektów, jeśli wiadomo, że co najmniej jeden z nich odnosi się do enum
stałej . ( equals
Metoda in Enum
jest final
metodą, która po prostu wywołuje super.equals
argument i zwraca wynik, tym samym porównując tożsamość.)
Ta gwarancja jest na tyle silna, że Josh Bloch zaleca, aby upierać się przy używaniu wzorca singletonu, najlepszym sposobem na jego wdrożenie jest użycie jednego elementu enum
(patrz: Skuteczna Java 2. wydanie, pozycja 3: Egzekwowanie właściwości singletonu za pomocą prywatny konstruktor lub typ enum ; także bezpieczeństwo wątków w Singleton )
Jakie są różnice między ==
i equals
?
Dla przypomnienia należy powiedzieć, że ogólnie ==
NIE jest realną alternatywą dla equals
. Gdy jednak tak jest (np. Z enum
), należy wziąć pod uwagę dwie ważne różnice:
==
nigdy nie rzuca NullPointerException
enum Color { BLACK, WHITE };
Color nothing = null;
if (nothing == Color.BLACK); // runs fine
if (nothing.equals(Color.BLACK)); // throws NullPointerException
==
podlega kontroli zgodności typu w czasie kompilacji
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!
Czy ==
należy stosować, jeśli dotyczy?
Bloch wspomina w szczególności, że niezmienne klasy, które mają odpowiednią kontrolę nad swoimi instancjami, mogą zagwarantować ==
użyteczność ich klientom . enum
jest konkretnie wspomniany jako przykład.
Punkt 1: Rozważ statyczne metody fabryczne zamiast konstruktorów
[...] pozwala niezmiennej klasie dać gwarancję, że nie istnieją dwa równe przypadki: a.equals(b)
wtedy i tylko wtedy a==b
. Jeśli klasa zapewni tę gwarancję, wówczas jej klienci mogą użyć ==
operatora zamiast equals(Object)
metody, co może spowodować lepszą wydajność. Typy Enum zapewniają tę gwarancję.
Podsumowując, argumenty za korzystanie ==
na enum
to:
- To działa.
- Jest szybsze.
- Jest bezpieczniejszy w czasie wykonywania.
- Jest bezpieczniejszy w czasie kompilacji.