Mit dem Enum Keyword ist es seit Java 5 möglich, eigene Aufzählungstypen zu erstellen. Die Typen können genutzt werden, um Optionen zu definieren. Zum Beispiel können wir mit Enums nur bestimmte Zahlen repräsentieren. So kann sichergestellt werden, dass nur spezifische Werte übergeben werden können. Und nicht wie bei einem Integer üblich jeglicher Wert. Außerdem steigt dadurch die Lesbarkeit des Quelltextes.
Angenommen, wir haben ein Objekt vom Typ Fernseher. Dieser besitzt verschiedene Kanäle. Das lässt sich theoretisch mit einem Integer umsetzen. Allerdings lassen sich mit einem Integer mehr Kanäle abbilden, als der Fernseher besitzt. Zusätzlich hat der Fernseher noch verschiedene Möglichkeiten für seinen Status: aus (0), an (1), Stand-by (2). Allerdings gibt es keine Typen an der Stelle 3 bei einem Integer könnte nun alles übergeben werden.
Unsere Klasse Fernseher
mit Integers könnte jetzt zum Beispiel so aussehen. Wir können nicht erkennen, welcher Status erlaubt ist und welcher Kanäle möglich sind. Wenn wir jetzt basierend auf den Status bestimmte Methoden nutzen, wäre es nicht möglich zu erkennen, was erlaubt ist und der Compiler könnte auch nicht abbrechen.
public class Fernseher {
private int channel;
private int status;
Fernseher(int status,int channel){
this.status = status;
this.channel = channel;
}
public void setStatus(int status) {
this.status = status;
}
public int getStatus() {
return status;
}
public void setChannel(int channel){
this.channel = channel;
}
public int getChannel(){
return channel;
}
}
Wenn wir uns nun ein Fernseher erzeugen und den Status Abfragen erhalten wir den Integer 2
zurück. Die Zahl alleine gibt uns keinerlei Informationen, die uns weiterhelfen, um den Status des Fernsehers festzustellen.
Fernseher fernseher = new Fernseher(2,10);
if(fernseher.getStatus() == 2){
System.out.println("Fernseher befindet sich im Stand-By");
}
Für uns haben wir den Status Stand-by als 2 definiert, leider haben wir die Information nirgends festgehalten und das Beispiel ist schlecht lesbare.
Sinnvoller wäre es jetzt, wenn wir eine Auflistung von Zuständen anstelle von Integers hätten: Aus, An, Stand-by.
Der gewünschte Typ, den wir jetzt benötigen, ist ein enum
. Von der grundlegenden Struktur wird er wie im nachfolgenden Code aufgebaut.
public enum <EnumName>{
EnumValue01, EnumValue2, EnumValue3
}
Um diese jetzt auf unsere Zustände anzuwenden, können wir private int Status
durch folgenden Konstrukt austauschen – dort haben wir jetzt ein enum
Status mit unseren 3 Typen definiert, die wir nutzen können.
private status status;
public enum status{
AUS, AN, STANDBY
}
Der Vorteil ist, dass wir jetzt auch unseren Methoden setStatus
und getStatus
geändert haben. (Am Ende des Artikels findest du noch einmal die komplette Klasse)
Nun können wir deutlich einfachere if-Abfragen durchführen, da unsere IDE uns die möglichen Status bereits zur Auswahl vorschlägt und wir uns keine Integer mehr merken müssen und auch nur unsere begrenzte Auswahl angeben können! Ein Aufruf könnte jetzt folgendermaßen unsere Leben erleichtern.
Fernseher fernseher = new Fernseher(Fernseher.Status.STANDBY, 2);
if(fernseher.getStatus() == Fernseher.Status.STANDBY){
System.out.println("Fernseher befindet sich im Stand-By");
}
Hier brauchen wir uns nicht einen bestimmten Integer merken, der für den jeweiligen Status steht, sondern können mit einem definierten Wert arbeiten. Falls wir jetzt einen Integer für den Status eintragen würden, erhielten wir sofort einen entsprechenden Fehler. Wie du siehst, ist diese Variante deutlich lesbarer als die Erste.
Bei den Kanälen haben wir die Besonderheit, in bestimmten Fällen wollen wir auch eine spezifische Nummer haben und nicht einen Enum vom Typen Channel. Deswegen gibt es die Möglichkeit bei enums
auch Konstruktoren und Felder zur Verfügung zustellen, wie wir es von Klassen kennen.
Unser Channel hat drei Kanäle: SatZwei, KabelDrei und ProAcht. Diese haben jeweils eine Nummer und einen spezifischeren Namen. So können auch viele weitere Daten mitgegeben werden.
private Channel channel;
public enum Channel{
SATZWEI(2, "SatZwei"),
KABELDREI(3, "KabelDrei"),
PROACHT(8, "ProAcht");
public int channelNumber;
public String channelName;
Channel(int i, String name) {
this.channelNumber = i;
this.channelName = name;
}
}
Nachfolgendes Beispiel zeigt, wie einfach du nun auf die Werte zugreifen kannst. Theoretisch muss das nicht in der Klasse Fernseher definiert werden, es kann auch eine separate Datei, unabhängige Klasse Channel erstellt werden, um damit weiterzuarbeiten. Der Einfachheit halber habe ich hier darauf verzichtet, um dir das Konzept von enums
zu erklären.
Fernseher fernseher = new Fernseher(Fernseher.Status.STANDBY, Fernseher.Channel.KABELDREI);
Fernseher.Channel currentChannel = fernseher.getChannel();
if(currentChannel == Fernseher.Channel.KABELDREI){
System.out.printf("Fernseher befindet sich auf dem Kanal %s (%d)",currentChannel.channelName,currentChannel.channelNumber);
}
Abschließende findest du hier noch einmal eine Übersicht der Klasse Fernseher, diese kann nach belieben ergänzt und erweitert werden. Wie wäre es, wenn du noch einen enum
für die verschiedenen Input Möglichkeiten wie HDMI, VGA, DisplayPort und viele weitere als kleine Übung schreibst.
Wenn auch das funktioniert, kannst du noch jedes enum in eine eigene Datei auslagern.
public class Fernseher {
private Status status;
public enum Status{
AUS, AN, STANDBY
}
private Channel channel;
public enum Channel{
SATZWEI(2, "SatZwei"),
KABELDREI(3, "KabelDrei"),
PROACHT(8, "ProAcht");
public int channelNumber;
public String channelName;
Channel(int i, String name) {
this.channelNumber = i;
this.channelName = name;
}
}
Fernseher(Status status,Channel channel){
this.status = status;
this.channel = channel;
}
public void setStatus(Status status) {
this.status = status;
}
public Status getStatus() {
return status;
}
public void setChannel(Channel channel){
this.channel = channel;
}
public Channel getChannel(){
return channel;
}
}
Wenn ein ENUM erwartet wird, ist es auch zulässig null
zu übergeben. Dieser Wert muss von deinem Code explizit abgefangen werden, wenn ein null
nicht erwünscht ist. Andernfalls funktioniert das Programm anders als erwartet oder bricht mit einer NullPointerException
ab.
Die folgende Zeile ist bezogen auf unser Beispiel vollkommen valide. Diese liegt daran, dass null
ein valider Wert für ein Objekt, wie auch unser Status
und Channel
, ist. Deshalb muss man beim Programmieren darauf achten, wie null
behandelt werden soll.
Fernseher fernseher = new Fernseher(null,null);
Eine Lösung für dieses Problem wäre unter anderem die folgende Lösung. Alternativ dazu könntest du auch default Values setzen, falls das bei deiner Klasse möglich ist.
...
Fernseher(Status status,Channel channel){
if (status == null || channel == null){
throw new IllegalArgumentException("Null is not a Valid Value");
}
this.status = status;
this.channel = channel;
}
...
Grade um die Lesbarkeit des Codes zu erhöhen, sind Enums (Aufzählungstypen) in Java und auch in anderen Programmiersprachen nützlich. Grade bei HTTP Statuscodes kommen Enums unter anderem häufig zur Verwendung.
Hinterlasse mir gerne einen Kommentar zum Artikel und wie er dir weitergeholfen hat beziehungsweise, was dir helfen würde das Thema besser zu verstehen. Oder hast du einen Fehler entdeckt, den ich korrigieren sollte? Schreibe mir auch dazu gerne ein Feedback!
Es sind noch keine Kommentare vorhanden? Sei der/die Erste und verfasse einen Kommentar zum Artikel "Wofür sind Enums in Java nützlich? Die Lesbarkeit Erhöhen!"!