Java Enum was bringt das und wie verwendet man es?

5 Antworten

In Java sind Enums finale Klassen mit einem nach außen hin nicht sichbaren Konstruktor. Diese merkwürdige Umsetzung ist dem Umstand geschuldet, dass dieses Konstrukt erst später dem Sprachschatz hinzugefügt wurde. Zu diesem Zeitpunkt war es dann wohl die noch eleganteste Lösung, es irgendwie hineinzuwurschteln.^^

Enumerationen generell sind, wie es der Name bereits sagt, Aufzählungen. Jedes Element in der Aufzählung ist konstant und statisch.

Nehmen wir einmal ein Beispiel. Ich möchte einen Kalender entwickeln, habe also eine Klasse Kalender. Diese soll eine Eigenschaft besitzen, die den aktuellen Monat angibt. Jeder Monat wird mit einer Zahl assoziiert, bei Januar beginnend mit 0. Da sich diese Variablen nicht ändern sollen, sind sie konstant. Der 1. Ansatz wäre wohl dieser:

final int JANUARY = 0;
final int FEBRUARY = 1;
final int MARCH = 2;
final int APRIL = 3;
// etc.

Insgesamt hätte ich 12 Konstanten. Die flattern nun aber etwas lose in meiner Klasse herum, ohne Relation zueinander. Stell dir einmal diesen Fall vor:

final int JANUARY = 0;
final int BLABLA = 5;
final int FEBRUARY = 1;
// etc.

BLABLA ist ebenso eine zugreifbare Konstante, die ebenso eine Jahreszeit beschreiben könnte, der Datentyp passt ja. Aber sie hat keinen Bezug zur Jahreszeit. Innerhalb des Programmcodes wirkt das unaufgeräumt und unübersichtlich. Also ordne ich alle zusammengehörigen Werte in einem Enum:

enum Jahreszeit { JANUARY, FEBRUARY, MARCH, APRIL /* etc. */ }

Ein weiterer Vorteil kommt nun zum Vorschein. Stell dir vor, wir wollen mit einer Setter-Methode die Jahreszeit setzen.

public void setJahreszeit(int jahreszeit) {
   this.jahreszeit = jahreszeit;
}

Jemand könnte auf die Idee kommen, setJahreszeit(100) aufzurufen. Der Datentyp stimmt, der Wert allerdings nicht. Ein Enum kann die Wertemenge einschränken. Statt der oberen Methode würde die neue Version so aussehen:

public void setJahreszeit(Jahreszeit jahreszeit) {
   this.jahreszeit = jahreszeit;
}

Nun gibt es nur noch die Möglichkeit, einen vordefinierten Typ des Enums zu übergeben. Datentyp und -wert sind sicher.

Je nach Sprache, können Enumtypen ein Wert (Index) zugeordnet werden. Z.B.:

enum Richtungen { Links = 0, Rechts = 1 } // Index wird zugewiesen

enum Tier { Panda = 3, Giraffe, Puma, Loewe } // Startindex, die weiteren Typen zaehlen automatisch hoch

Wenn kein Index zugeordnet wird, beginnt die Zählung bei 0. Im Falle der Enumeration Tier wäre der Panda die 0, der Puma bereits die 2, usw..

Enums in Java:

Jedes Enum erbt von der Klasse Enum und wird mit dem Schlüsselwort enum eingeleitet. Der Konstruktor ist, wie bereits erwähnt, privat - damit stellen Enums in Java ein perfektes Beispiel für ein Singleton Pattern dar (von dem Enum können keine Instanzen erzeugt werden). Wäre der Konstruktor nicht privat, wäre das ganze Prinzip dahin, denn man könnte ja auf die Idee kommen, doch noch andere Enum-Instanzen hinzuzufügen, die plötzlich gar nicht mehr dem Kontext entsprechen (z.B. eine Ente zu einer Enumeration für Möbelstücke). 

Hier ein Beispiel, wie den Enum-Typen Werte zugeordnet werden. Es gibt eine Eigenschaft, die über den Konstruktor gesetzt wird. Sogar Methoden können definiert werden.

public enum Farbe {

RED("#ff0000"), BLUE("#0000ff"), GREEN("#00ff00")
private string farbCode;
private Farbe(string farbcode){ this.farbCode = farbCode; }
public string getFarbCode(){ return this.farbCode; }
}

Oben erfolgt die Aufzählung der Enum-Typen. Jeder Typ ruft im Grunde seinen Konstruktor auf, um der Eigenschaft ihren Wert zu übergeben.

Der Compiler macht dann ungefähr das daraus:

public final class Farbe extends Enum {

public static final Farbe RED = new Farbe("RED", 0, "#ff0000"); public static final Farbe BLUE = new Farbe("BLUE", 1, "#0000ff"); public static final Farbe GREEN = new Farbe("GREEN", 2, "#00ff00");
private string farbCode;
private Farbe(String name, int index, string farbCode){ super(name, index);
this.farbCode = farbCode;
}
public string getFarbCode(){ return this.farbCode; } }

Zusätzlich zu unserer Eigenschaft werden vermutlich noch Name und evt. sogar der Index als Parameter für den Konstruktor verwendet.

Wieso die Klasse in Java final ist, wird hier schön erklärt: http://stackoverflow.com/questions/1884433/java-enum-inheritance

Weitere Informationen zu Enums in Java findest du außerdem hier: http://openbook.rheinwerk-verlag.de/javainsel9/javainsel_09_004.htm#mj2f6d324dfd3b9293fe6312045c460ad3

Enums sind "Klassen", welche man dazu verwenden kann um den Code leichter lesbar zu machen. Ebenso helfen diese auch Parametereingaben zu beschränken. Beispiel:

enum Direction {
   North, East, West, South;
}


class MyClass {
    
   public void move(Direction direction) {
       ....
       if (Direction.NORTH.equals(direction) {
           moveNorth();
       }
       ....
   }
}

So ließe sich die Methode move so aufrufen:

MyClass myClass = new MyClass();
myClass.move(Direction.North);

Mit enums kann man jedoch noch viel mehr machen, wie aus dem Stackoverflow link von New2016 zu lesen ist. 

Vieles ließe sich auch mit Konstanten umsetzen und würde weniger Speicher verbrauchen, jedoch habe ich einfach nur ein Beispiel genannt, wofür Enums sinnvoll wären.

Enums sind immer gut wenn du eine bestimmte Anzahl an Zuständen (größer zwei weil sonstreicht Boolean) darstellen willst. Für diese kommst du dann in den Genuss z.b effizienter Vergleichs Operationen und Konstruktion. (bei Strings gerne mal teuer) IDEs bieten dir Unterstützung durch code completion (man muss sich nicht mehr ganz genau merken wie die Zustände jetzt hießen.) und ganz großer Vorteile: Tippfehler sind ausgeschlossen da der Compiler Alarmschlagen würde.

Was bringt es? Naja, es sind nur vorher definierte Werte für eine Variable möglich. Angenommen du hast ein 2D Spiel und die Figur hat die Methode Spielfigur.Bewegen(String richtung), dann musst du dir merken, ob es "Spielfigur.Bewegen("right")", "Spielfigur.Bewegen("rechts")" oder "Spielfigur.Bewegen("Rechts")" heißt!

Mit Enum kannste das enum "Richtung" mit den Werten "LINKS", "RECHTS", ... festlegen und dann die Methode "Spielfigur.Bewegen(Richtung richtung)" so aufrufen: "Spielfigur.Bewegen(Richtung.LINKS)".

Woher ich das weiß:Studium / Ausbildung – Informatikstudium