EMZETT.
Login

Enum

Kurz: Ein eigener Typ für eine feste, begrenzte Menge benannter Konstanten — z. B. Wochentage oder Status-Werte, bei denen nur bestimmte Werte gültig sein dürfen.

Genauer: Ein enum ist technisch eine spezielle Klasse, kann also auch eigene Felder, Konstruktoren und Methoden haben. Der große Vorteil gegenüber einfachen String- oder int-Konstanten: der Compiler verhindert ungültige Werte, ein switch über ein Enum kann vom Compiler sogar auf Vollständigkeit geprüft werden.

enum Status { OFFEN, IN_BEARBEITUNG, ERLEDIGT }

Im Detail

enum Status {
    OFFEN("Wartet auf Bearbeitung"),
    IN_BEARBEITUNG("Wird aktuell bearbeitet"),
    ERLEDIGT("Abgeschlossen");
 
    private final String beschreibung; // jede Konstante trägt einen eigenen Wert
 
    Status(String beschreibung) { // Enum-Konstruktor, immer private (implizit)
        this.beschreibung = beschreibung;
    }
 
    public String getBeschreibung() {
        return beschreibung;
    }
}
 
Status s = Status.IN_BEARBEITUNG;
System.out.println(s.getBeschreibung());
 
switch (s) {
    case OFFEN -> System.out.println("Noch nicht begonnen");
    case IN_BEARBEITUNG -> System.out.println("Läuft");
    case ERLEDIGT -> System.out.println("Fertig");
    // kein default nötig - Compiler weiß, dass alle 3 Werte abgedeckt sind
}

Der entscheidende Vorteil gegenüber String-Konstanten ("OFFEN", "IN_BEARBEITUNG", …): Tippfehler wie "OFFN" fallen bei einem enum sofort beim Kompilieren auf, bei Strings erst (wenn überhaupt) zur Laufzeit. Enums bieten außerdem eingebaute Methoden wie values() (liefert ein Array aller Konstanten, praktisch für Schleifen) und ordinal() (liefert die Position, 0-basiert) sowie name() (liefert den Konstantennamen als String). Enum-Werte sind Singletons — Status.OFFEN ist im gesamten Programm immer exakt dasselbe Objekt, weshalb ==-Vergleiche bei Enums (anders als bei den meisten anderen Objekten) tatsächlich sicher und üblich sind.

Über alle Werte iterieren

for (Status s : Status.values()) {
    System.out.println(s.name() + " (Position " + s.ordinal() + "): " + s.getBeschreibung());
}
 
// String -> Enum umwandeln (wirft IllegalArgumentException bei ungültigem Namen)
Status gefunden = Status.valueOf("ERLEDIGT");

ordinal() ist verlockend, aber riskant, wenn Reihenfolge außerhalb des Programms persistiert wird (z. B. in einer Datenbank) — fügt man später eine neue Konstante MITTEN in die Enum-Definition ein, verschieben sich alle nachfolgenden ordinal()-Werte, was gespeicherte Werte plötzlich falsch interpretiert. Für persistierte Daten ist name() (der Konstantenname als String) die stabilere, robustere Wahl.

Enums mit abstrakten Methoden — je Konstante unterschiedliches Verhalten

Ein fortgeschrittenes, aber mächtiges Muster: jede Enum-Konstante kann ihre EIGENE Implementierung einer abstrakten Methode mitbringen, ähnlich wie bei Polymorphie:

enum Operation {
    PLUS { public int berechne(int a, int b) { return a + b; } },
    MINUS { public int berechne(int a, int b) { return a - b; } };
 
    public abstract int berechne(int a, int b);
}
 
System.out.println(Operation.PLUS.berechne(3, 4)); // 7

Das ersetzt in vielen Fällen eine sonst nötige switch-Verzweigung über den Enum-Wert und hält die jeweilige Logik direkt bei der zugehörigen Konstante.

EnumMap und EnumSet

Für Collections, deren Schlüssel/Elemente Enum-Werte sind, bieten EnumMap und EnumSet deutlich bessere Performance als HashMap/HashSet, weil sie intern ein einfaches Array statt einer Hash-Tabelle nutzen (die Position im Array entspricht dem ordinal()-Wert):

EnumMap<Status, Integer> anzahl = new EnumMap<>(Status.class);
anzahl.put(Status.OFFEN, 5);
anzahl.put(Status.ERLEDIGT, 12);
 
EnumSet<Status> aktiveStatus = EnumSet.of(Status.OFFEN, Status.IN_BEARBEITUNG);

Siehe auch: Constants (final), Switch-Statement, Classes