Kann ==
verwendet werden enum
?
Ja: Aufzählungen verfügen über strenge Instanzsteuerelemente, mit denen Sie ==
Instanzen vergleichen können. Hier ist die Garantie der Sprachspezifikation (Hervorhebung von mir):
Ein Aufzählungstyp hat keine anderen Instanzen als die durch seine Aufzählungskonstanten definierten.
Es ist ein Fehler beim Kompilieren, wenn versucht wird, einen Aufzählungstyp explizit zu instanziieren. Die final clone
Methode in Enum
stellt sicher, dass enum
Konstanten niemals geklont werden können, und die spezielle Behandlung durch den Serialisierungsmechanismus stellt sicher, dass niemals doppelte Instanzen als Ergebnis der Deserialisierung erstellt werden. Die reflektierende Instanziierung von Aufzählungstypen ist verboten. Zusammen stellen diese vier Dinge sicher, dass keine Instanzen eines enum
Typs existieren, die über die durch die enum
Konstanten definierten hinausgehen .
Da es nur eine Instanz jeder enum
Konstante gibt, ist es zulässig, den ==
Operator anstelle der equals
Methode zu verwenden, wenn zwei Objektreferenzen verglichen werden, wenn bekannt ist, dass mindestens eine von ihnen auf eine enum
Konstante verweist . (Die equals
Methode in Enum
ist eine final
Methode, die lediglich super.equals
ihr Argument aufruft und das Ergebnis zurückgibt, wodurch ein Identitätsvergleich durchgeführt wird.)
Diese Garantie ist stark genug, die Josh Bloch empfiehlt. Wenn Sie darauf bestehen, das Singleton-Muster zu verwenden, können Sie es am besten implementieren, indem Sie ein einzelnes Element verwenden enum
(siehe: Effektive Java 2nd Edition, Punkt 3: Erzwingen Sie die Singleton-Eigenschaft mit a privater Konstruktor oder ein Aufzählungstyp ; auch Thread-Sicherheit in Singleton )
Was sind die Unterschiede zwischen ==
und equals
?
Zur Erinnerung muss gesagt werden, dass dies im Allgemeinen ==
KEINE Alternative ist equals
. Wenn dies jedoch der Fall ist (z. B. bei enum
), sind zwei wichtige Unterschiede zu berücksichtigen:
==
wirft nie NullPointerException
enum Color { BLACK, WHITE };
Color nothing = null;
if (nothing == Color.BLACK); // runs fine
if (nothing.equals(Color.BLACK)); // throws NullPointerException
==
wird zur Kompilierungszeit einer Typpompatibilitätsprüfung unterzogen
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!
Sollte ==
gegebenenfalls verwendet werden?
Bloch erwähnt ausdrücklich, dass unveränderliche Klassen, die die richtige Kontrolle über ihre Instanzen haben, ihren Kunden garantieren können, dass sie ==
verwendbar sind. enum
wird ausdrücklich als Beispiel erwähnt.
Punkt 1: Betrachten Sie statische Factory-Methoden anstelle von Konstruktoren
[...] es ermöglicht einer unveränderlichen Klasse, die Garantie zu geben, dass keine zwei gleichen Instanzen existieren: a.equals(b)
genau dann, wenn a==b
. Wenn eine Klasse diese Garantie übernimmt, können ihre Clients den ==
Operator anstelle der equals(Object)
Methode verwenden, was zu einer verbesserten Leistung führen kann. Aufzählungstypen bieten diese Garantie.
Zusammenfassend sind die Argumente für die Verwendung von ==
on enum
:
- Es klappt.
- Es ist schneller.
- Zur Laufzeit ist es sicherer.
- Beim Kompilieren ist es sicherer.