Was sind eigentlich Enumerations und wozu dienen sie? v.5.0

Enumerations oder Aufzählungstypen stellen einen Datentyp dar, der eine höchst flexible Bereitstellung von Konstanten ermöglicht.

Die bekannte Methode der Bereitstellung von Konstanten durch static final deklarierte Klassenvariablen hat den erheblichen Nachteil der fehlenden Typsicherheit. Das folgende Beispiel demonstriert dies:


public class Typsicherheit {
    
    private enum Fahrzeug {AUTO, LKW}
    
    private static int AUTO = 0;
    private static int LKW = 2;
    
    private static int SCHREINER = 0;
    private static int METZGER = 1;

    public static void main(String[] args) {
        int fahrzeug;
        fahrzeug = AUTO;                                    // ok
        System.out.println("Fahrzeug: " + fahrzeug);        
        fahrzeug = METZGER;                                    // ok, aber falsche Zuweisung
        System.out.println("Fahrzeug: " + fahrzeug);        
        // fahrzeug = Fahrzeug.AUTO;                        // Compile-Error
        Fahrzeug vehicle;
        vehicle = Fahrzeug.AUTO;                            // ok
        System.out.println("Fahrzeug: " + vehicle);    
    }
}

Es ist offensichtlich, dass hier der int-Variablen fahrzeug eine falsche Konstante zugewiesen wird.
Anders verhält es sich mit dem enum-Typ Fahrzeug. Seine (implizit finale, statische) Deklaration erfolgt durch die durch Kommata separierte Aufzählung von groß geschriebenen Werten. Eine Objektbildung durch new kann ebenso wenig erfolgen wie ein späteres Hinzufügen weiterer Werte.
Das Abrufen eines Wertes erfolgt ähnlich demjenigen irgend einer anderen beliebigen statischen Variablen durch Nennung des Typbezeichners (hier Fahrzeug) und dem gewünschten Wert (hier AUTO) verbunden durch den Punkt-Operator.
Die Zuweisung eines solchen Wertes an z.B. einen int-Wert scheitert an der Typprüfung des Compilers.
Das folgende Beispiel demonstriert einige Möglichkeiten des Umgangs von enum-Werten anhand von Motorrad-Typen. Wie in einer 'normalen' Klasse können auch Konstruktoren und Members deklariert werden. Besitzen Konstruktoren Parameter, muessen den Elementen der Konstantenliste entsprechende Argumente mitgegeben werden, die wie bekannt zur Initialisierung von Instanzvariablen genutzt und über Getter- und Setter-Methoden manipuliert werden können. Die Übergabe erfolgt für alle Konstanten zur Laufzeit wenn ein enum-Objekt geladen wird.

public enum BMW {
    R1100S(98, 229), K1200RS(130, 285), R75_5(50, 210);

    int ps, gewicht;

    BMW(int ps, int gewicht) {
        this.ps = ps;
        this.gewicht = gewicht;
    }

    public int getPS() {
        return ps;
    }

    public int getGewicht() {
        return this.gewicht;
    }

    public void setGewicht(int gewicht) {
        this.gewicht = gewicht;
    }

    public int tune() {
        int mehr = this.getPS() / 10;
        return this.getPS() + mehr;
    }

    public String toString() {
        switch (this) {
        case R1100S:
            return "BMW R 1100 S";
        case K1200RS:
            return "BMW K 1200 RS";
        case R75_5:
            return "BMW R 75/5";
        }
        return "";
    }

    public static void main(String[] args) {
        System.out.println("Die " + BMW.R1100S.toString() + " hat "
                + BMW.R1100S.getPS() + " PS");
        System.out.println("Eine getunte " + BMW.R1100S.toString()
                + " leistet " + BMW.R1100S.tune() + " PS");
        System.out.println("Eine getunte " + BMW.K1200RS.toString()
                + " leistet " + BMW.K1200RS.tune() + " PS");
        BMW knoscher = BMW.R75_5;
        knoscher.setGewicht(180);
        System.out.println("Eine von KnoScher abgespeckte Version der "
                + knoscher + " wiegt " + knoscher.getGewicht() + " Kg");
    }

}

Erwähnenswert sind die beiden Methoden toString() und name(). Beide geben den Bezeichner der enum- Konstanten zurück, allerdings ist name() im Gegensatz zu toString() in der Oberklasse Enum als final deklariert, kann also nicht überschrieben werden. Für eine variierende Ausgabe sollte somit toString() verwendet werden.