Einleitung: Ein Fehler, den Sie vielleicht gerade machen
\n\nStellen Sie sich vor: Sie programmieren in Java, verwenden Aufzählungen (Enums) und müssen zwei Werte vergleichen. Automatisch schreiben Sie if (day == Day.MONDAY). Oder vielleicht if (day.equals(Day.MONDAY)). Welche Variante ist richtig? Und gibt es überhaupt einen Unterschied?
Diese Frage ist eine der beliebtesten auf Stack Overflow. Tausende Entwickler (vom Anfänger bis zum Senior) haben sie sich gestellt. Es scheint eine Kleinigkeit zu sein. Aber hinter dieser „Kleinigkeit“ verbirgt sich ein tiefes Verständnis dafür, wie die JVM funktioniert, wie Enums aufgebaut sind und warum in Java nicht alles so eindeutig ist.
\n\nIn diesem Artikel klären wir ein für alle Mal: Wie man Enums in Java richtig vergleicht, wann man == und wann equals() verwendet und warum eine dieser Optionen fast immer die beste Wahl ist.
Kurze Antwort für Ungeduldige
\n\nWenn Sie sofort eine Antwort brauchen – verwenden Sie ==.
Aber! Bevor Sie den Artikel schließen, lassen Sie uns verstehen, warum das so ist und welche Fallstricke Sie erwarten könnten. Denn der Teufel steckt, wie immer, im Detail.
\n\nWarum ist ein Enum nicht nur eine Sammlung von Konstanten?
\n\nUm den Unterschied zwischen == und equals() zu verstehen, muss man sich daran erinnern, was ein Enum in Java eigentlich ist.
Jedes Enum ist eine vollwertige Klasse, die implizit von java.lang.Enum erbt. Jede Enum-Konstante ist eine statische finale Instanz dieser Klasse. Die JVM garantiert, dass es für jeden Enum-Wert genau ein Objekt im Speicher gibt.
Sehen Sie sich diesen Code an:
\n\npublic enum Day {\n MONDAY,\n TUESDAY,\n WEDNESDAY,\n THURSDAY,\n FRIDAY,\n SATURDAY,\n SUNDAY\n}\n\nWenn die JVM dieses Enum lädt, erstellt sie genau 7 Objekte. Day.MONDAY ist immer ein und dasselbe Objekt. Immer. Und das ist der entscheidende Punkt.
Vergleich mit ==: Warum funktioniert das?
\n\nDer Operator == in Java vergleicht Referenzen auf Objekte. Er schaut nicht auf den Inhalt – er prüft, ob zwei Variablen auf dasselbe Objekt im Speicher verweisen.
Da die JVM die Eindeutigkeit jeder Enum-Instanz garantiert, funktioniert der Vergleich mit == für Enums einwandfrei:
public class EnumComparison {\n public static void main(String[] args) {\n Day today = Day.WEDNESDAY;\n Day anotherDay = Day.WEDNESDAY;\n \n // Beide Variablen verweisen auf dasselbe Objekt im Speicher\n System.out.println(today == anotherDay); // true\n \n // Vergleich mit einer anderen Konstante\n System.out.println(today == Day.MONDAY); // false\n }\n}\n\nAusgabe:
\ntrue\nfalse\n\nEinfach und elegant. Aber schauen wir uns an, was unter der Haube passiert.
\n\nWarum ist das sicher? Garantien der JVM
\n\nDie Java Language Specification (JLS 8.9) garantiert, dass jeder Enum-Wert genau einmal beim Laden der Klasse initialisiert wird. Weder durch Reflektion, Serialisierung oder Klonen können Sie ein Duplikat erstellen. Selbst wenn Sie versuchen, new zu verwenden – der Compiler gibt einen Fehler aus.
Daher ist == für Enums nicht nur „es funktioniert“, sondern die schnellste und zuverlässigste Methode des Vergleichs.
Vergleich mit equals(): Funktioniert, aber es gibt Nuancen
\n\nDie Methode equals() funktioniert ebenfalls. Die Klasse Enum überschreibt equals() und verwendet intern ==:
// Echter Code aus java.lang.Enum\npublic final boolean equals(Object other) {\n return this == other;\n}\n\nDas heißt, der Aufruf day.equals(Day.MONDAY) macht letztendlich dasselbe wie day == Day.MONDAY. Aber es gibt einen wichtigen Unterschied:
Das Problem mit null
\n\nWenn Ihre Variable null sein könnte