Zum Inhalt springen
Java Anfänger 20 min

Enums

Enums in Java: Fest definierte Wertemengen, Enums mit Feldern und Methoden, EnumSet und praktische Anwendungen.

Aktualisiert:

Enums in Java

Was ist besser: status = 1 oder status = Status.AKTIV? Natuerlich die zweite Variante! Enums (Aufzaehlungstypen) definieren eine feste Menge von Werten — typsicher, lesbar und fehlerfrei.

Was sind Enums?

Ein Enum ist ein spezieller Typ, der eine feste Anzahl von Konstanten definiert:

public enum Wochentag {
    MONTAG, DIENSTAG, MITTWOCH, DONNERSTAG,
    FREITAG, SAMSTAG, SONNTAG
}
var heute = Wochentag.MITTWOCH;
System.out.println(heute); // MITTWOCH

// In switch verwenden
var nachricht = switch (heute) {
    case MONTAG -> "Wochenstart!";
    case FREITAG -> "Fast Wochenende!";
    case SAMSTAG, SONNTAG -> "Wochenende!";
    default -> "Mitten in der Woche.";
};
System.out.println(nachricht);

Warum Enums statt Konstanten?

// SCHLECHT: "Magic Numbers"
int status = 1; // Was bedeutet 1?
if (status == 2) { } // Was ist 2?

// SCHLECHT: String-Konstanten
String farbe = "rot"; // Tippfehler moeglich: "Rot", "ROT", "rott"

// GUT: Enums
enum Status { AKTIV, INAKTIV, GESPERRT }
enum Farbe { ROT, GRUEN, BLAU }

var status = Status.AKTIV;
var farbe = Farbe.ROT;

Enums mit Feldern und Konstruktoren

Enums koennen Felder, Konstruktoren und Methoden haben:

public enum Planet {
    MERKUR(3.303e+23, 2.4397e6),
    VENUS(4.869e+24, 6.0518e6),
    ERDE(5.976e+24, 6.37814e6),
    MARS(6.421e+23, 3.3972e6),
    JUPITER(1.9e+27, 7.1492e7),
    SATURN(5.688e+26, 6.0268e7),
    URANUS(8.686e+25, 2.5559e7),
    NEPTUN(1.024e+26, 2.4746e7);

    private final double masse;     // in kg
    private final double radius;    // in m

    Planet(double masse, double radius) {
        this.masse = masse;
        this.radius = radius;
    }

    public double getMasse() { return masse; }
    public double getRadius() { return radius; }

    // Berechnete Eigenschaft
    public double oberflaeche() {
        return 4 * Math.PI * radius * radius;
    }

    public double gravitationsBeschleunigung() {
        final double G = 6.67300E-11;
        return G * masse / (radius * radius);
    }
}
for (var planet : Planet.values()) {
    System.out.printf("%-10s g = %.2f m/s²%n",
        planet, planet.gravitationsBeschleunigung());
}

Ausgabe:

MERKUR     g = 3.70 m/s²
VENUS      g = 8.87 m/s²
ERDE       g = 9.80 m/s²
...

Enum-Methoden

Jeder Enum hat eingebaute Methoden:

enum Jahreszeit { FRUEHLING, SOMMER, HERBST, WINTER }

// values() -- Alle Werte als Array
for (var j : Jahreszeit.values()) {
    System.out.println(j);
}

// valueOf() -- String zu Enum
var sommer = Jahreszeit.valueOf("SOMMER");

// name() -- Name als String
System.out.println(sommer.name()); // "SOMMER"

// ordinal() -- Position (0-basiert)
System.out.println(sommer.ordinal()); // 1

// Vergleich
System.out.println(sommer == Jahreszeit.SOMMER); // true (bei Enums OK!)

Wichtig: Bei Enums darfst du == verwenden (statt equals()), weil es von jedem Enum-Wert nur eine einzige Instanz gibt.

Enums mit abstrakten Methoden

Jeder Enum-Wert kann seine eigene Implementierung haben:

public enum Rechenoperation {
    ADDITION {
        @Override
        public double berechne(double a, double b) { return a + b; }
    },
    SUBTRAKTION {
        @Override
        public double berechne(double a, double b) { return a - b; }
    },
    MULTIPLIKATION {
        @Override
        public double berechne(double a, double b) { return a * b; }
    },
    DIVISION {
        @Override
        public double berechne(double a, double b) {
            if (b == 0) throw new ArithmeticException("Division durch 0!");
            return a / b;
        }
    };

    public abstract double berechne(double a, double b);
}
var op = Rechenoperation.ADDITION;
System.out.println(op.berechne(10, 3)); // 13.0

for (var operation : Rechenoperation.values()) {
    System.out.printf("%s: 10 op 3 = %.1f%n",
        operation, operation.berechne(10, 3));
}

Enums mit Interfaces

interface Beschreibbar {
    String beschreibung();
}

public enum Schwierigkeit implements Beschreibbar {
    LEICHT("Fuer Anfaenger geeignet"),
    MITTEL("Grundkenntnisse erforderlich"),
    SCHWER("Fuer Fortgeschrittene"),
    EXPERTE("Nur fuer Profis");

    private final String text;

    Schwierigkeit(String text) {
        this.text = text;
    }

    @Override
    public String beschreibung() {
        return text;
    }
}

Praktische Beispiele

HTTP-Status-Codes

public enum HttpStatus {
    OK(200, "OK"),
    CREATED(201, "Created"),
    BAD_REQUEST(400, "Bad Request"),
    UNAUTHORIZED(401, "Unauthorized"),
    NOT_FOUND(404, "Not Found"),
    INTERNAL_SERVER_ERROR(500, "Internal Server Error");

    private final int code;
    private final String nachricht;

    HttpStatus(int code, String nachricht) {
        this.code = code;
        this.nachricht = nachricht;
    }

    public int getCode() { return code; }
    public String getNachricht() { return nachricht; }

    public boolean istErfolgreich() {
        return code >= 200 && code < 300;
    }

    public boolean istClientFehler() {
        return code >= 400 && code < 500;
    }
}

Zustandsmaschine

public enum BestellStatus {
    NEU {
        @Override
        public BestellStatus naechster() { return BEZAHLT; }
    },
    BEZAHLT {
        @Override
        public BestellStatus naechster() { return VERSENDET; }
    },
    VERSENDET {
        @Override
        public BestellStatus naechster() { return GELIEFERT; }
    },
    GELIEFERT {
        @Override
        public BestellStatus naechster() { return this; } // Endstatus
    };

    public abstract BestellStatus naechster();
}

var status = BestellStatus.NEU;
System.out.println(status);              // NEU
status = status.naechster();
System.out.println(status);              // BEZAHLT
status = status.naechster();
System.out.println(status);              // VERSENDET

Enum in switch (modern)

enum Ampel { ROT, GELB, GRUEN }

var ampel = Ampel.ROT;

var aktion = switch (ampel) {
    case ROT -> "Stehen bleiben!";
    case GELB -> "Achtung!";
    case GRUEN -> "Fahren!";
};
// Kein default noetig -- alle Werte abgedeckt!

Vergleich mit Python

# Python: Enum-Modul
from enum import Enum

class Farbe(Enum):
    ROT = 1
    GRUEN = 2
    BLAU = 3
// Java: Eigener Sprachbestandteil
enum Farbe {
    ROT, GRUEN, BLAU
}

Java-Enums sind maechtigter: Sie koennen Felder, Methoden, Konstruktoren und sogar Interfaces implementieren.

Uebungen

Uebung 1: Monat-Enum

Erstelle ein Enum Monat mit allen 12 Monaten. Fuege ein Feld tage (Anzahl der Tage) und eine Methode istLangerMonat() hinzu.

Uebung 2: Waehrung

Erstelle ein Enum Waehrung (EUR, USD, GBP, CHF) mit Wechselkursen. Fuege eine Methode umrechnen(double betrag, Waehrung ziel) hinzu.

Uebung 3: Prioritaet

Erstelle ein Enum Prioritaet (NIEDRIG, MITTEL, HOCH, KRITISCH) mit einer Methode istDringend(). Verwende es in einer einfachen Todo-Klasse.

Uebung 4: Kartenspiel

Erstelle Enums Kartenfarbe (KREUZ, PIK, HERZ, KARO) und Kartenwert (ZWEI bis ASS). Erstelle einen Record Spielkarte(Kartenfarbe farbe, Kartenwert wert).

Was kommt als Naechstes?

In der naechsten Lektion widmen wir uns Arrays — den grundlegenden Datenstrukturen fuer geordnete Sammlungen von Werten.

Zusammenfassung

  • Enums definieren eine feste Menge von Konstanten
  • Sie sind typsicher — keine falschen Werte moeglich
  • Enums koennen Felder, Konstruktoren und Methoden haben
  • Jeder Enum-Wert kann eine eigene Implementierung haben (abstrakte Methoden)
  • Enums koennen Interfaces implementieren
  • Vergleich mit == ist bei Enums sicher und empfohlen
  • values() liefert alle Werte, valueOf("NAME") konvertiert von String

Pro-Tipp: Verwende Enums ueberall dort, wo du eine fest definierte Menge von Werten hast: Status-Codes, Wochentage, Rollen, Kategorien. Sie machen deinen Code lesbarer und sicherer als String- oder int-Konstanten. Und in Switch Expressions mit Enums warnt dich der Compiler, wenn du einen Wert vergessen hast — das verhindert Bugs!

Zurück zum Java Kurs