Die Kontrollstruktur Switch-Case ist ein Konstrukt, das seit Java 1.0 existiert. Es ist gerade dann nützlich, wenn verschiedene Werte einem spezifischen Fall zugeordnet werden müssen. Hierbei ist zu beachten, dass in Java Switch-Case nicht mit komplexeren Abfragen umgehen kann. In Python zum Beispiel können dort ganze Abfragen oder auch Variablen durchgereicht werden. Mehr dazu im Python Artikel „Pattern Matching“.
In Java ist die Switch-Case-Anweisung eine, die auf den ersten Blick eine deutlich andere Syntax hat. Das kann Anfängern am Anfang etwas Schwierigkeiten bereiten. Vieles, das mit einem Switch-Case abgedeckt werden kann, kann auch über if-Abfragen realisiert werden. Warum diese Variante trotzdem Vorteile bietet, wirst du hier sehen!
Zu Anfang nun schon einmal der Hinweise, dass Switch-Case nicht mit jedem Datentypen umgehen kann, zum Beispiel fallen darunter boolean, long, float, double, da intern bei der Switch-Case-Methode alles als Ganzzahlen (int) dargestellt wird. Diese ist bei den obigen Datentypen entsprechende nicht möglich.
Der Infografik kannst du noch einmal alle Möglichkeiten entnehmen, die möglich sind. Objekte sind im Allgemeinen auch nicht erlaubt, bis auf die ergänzten Ausnahmen wie Strings und die Wrapper Objekte für die primitiven Datentypen, die eben erlaubt sind.
Wir wollen uns jetzt das erste Beispiel ansehen. Um eine Switch-Case-Anweisung einzuleiten, wird das Keyword switch verwendet. Danach folgen immer runde Klammern. Darinnen steht die Variable, die geprüft werden soll. Darunter werden mit dem Keyword case die einzelnen Fälle eingeleitet, die auftreten könnten. Nach dem Keyword case
steht ein Wert oder eine Konstante, die den Wert enthält, gefolgt von einem Doppelpunkt. Der Doppelpunkt leitet die Anweisung ein, die ausgeführt werden soll, falls der Fall eintritt. In unserem Beispiel geben wir dort einfach nur die entsprechenden Werte aus.
String chatShort = "LOL";
final String AFK = "afk";
switch (chatShort) {
case "fyi":
System.out.println("for your information / zu deiner Information");
break;
case "btw":
System.out.println("by the way / übrigens");
break;
case AFK:
System.out.println("away from keyboard / nicht an der Tastatur");
break;
case "gn":
System.out.println("good night / Gute Nacht");
break;
case "lol":
case "Lol":
case "LOL":
System.out.println("laughing out loud / laut loslachen");
break;
default:
System.out.println("keine Abkürzung gefunden");
break;
}
Das Ergebnis: Wenn unser String „LOL“ ist, wird auf der Konsole „laughing out loud / laut loslachen“ ausgeben.
Im oberen Beispiel ist der Fall für lol
, Lol
und LOL
besonders. Damit wollte ich dir zeigen, dass mehre case
-Statements die gleiche Anweisung besitzen können. Egal, ob unsere Variable chatShort
den Wert lol
, Lol
oder LOL
besitzt. Es wird immer laughing out loud / laut loslachen
in die Konsole geschrieben werden.
In dem oberen Fall sehen wir, dass wir das Keyword break
an mehreren Stellen verwenden. Damit beenden wir einen Durchlauf. Wie bei einer Schleife wird die Switch-Case-Anweisung beendet. Diese ist immer dann notwendig, wenn wir auf einen expliziten Fall prüfen wollen, ohne dass der nachfolgende Code ausgeführt wird.
Hätten wir den Code von oben ohne die break;
Keywords und die Eingabe in der Variable check
wäre „btw“ dann hätten wir auf der Konsole alle fünf nachfolgenden Fälle ausgeben. Das ist tatsächlich das gewünschte Verhalten und auch über verschiedene Programmiersprachen hinweg üblich. Zum Beispiel verhalten sich C++ und PHP auch so. Wobei C++ ab dem 17er-Standard ein Keyword anbietet, fallthrough, um diese noch mal zu verdeutlichen, damit klar ist, dass es wirklich gewünscht ist, auch wenn es keinen Einfluss auf den Compiler hat. Viele Personen verwirrt diese Eigenschaft am Anfang sehr. Die Konsolenausgabe bei „btw“ ohne break
wäre die folgende:
by the way / übrigens
away from keyboard / nicht an der Tastatur
good night / Gute Nacht
laughing out loud / laut loslachen
keine Abkürzung gefunden
Merke dir also: Immer wenn du auf den Einzelfall prüfen willst, solltest du mit dem Keyword break
arbeiten. Allerdings kannst du es auch in einem sinnvollen Kontext ohne break
für dich nutzen. Schau dir noch einmal das obige Beispiel an, da wird dir auffallen, dass „lol“ in drei Schreibweisen vorhanden ist. Bei dem ersten und zweiten Fall macht das Programm augenscheinlich gar nichts, aber wenn dieser Fall zutrifft, wird auch „laughing out …“ ausgegeben, weil kein Break dazwischen verwendet wurde. So können mehrere Cases an dieselbe Anweisung weitergereicht werden.
Nun können in einem Switch-Case nicht immer alle Fälle abgehandelt werden, weil wie wir oben schon gelernt haben, nur Strings, Integers und weitere Typen möglich sind, die eine unterschiedliche Anzahl an Varianten und Möglichkeiten haben. Dann kommt es schnell vor, dass wir einen Standardfall benötigen, um alle anderen abzufangen. Dafür existiert das Keyword default
, dieses entspricht dem else in einer if-Abfrage, das immer als Letztes ausgeführt wird, falls nicht ein vorheriger Fall bereits zutrifft. Im obigen Code Beispiel verwenden wir den Standardfall, um dem Nutzer zu sagen, dass seine Eingabe keine passende Lösung hat. In unserem Beispiel haben wir den default
Case am Ende stehen, diese ist theoretisch nicht notwendig. Aber der Verständlichkeit sollte dieser definitiv immer am Ende stehen.
Seit Java 14 sind einige neuen Syntax-Optionen hinzugekommen. Dazu unten auch noch mal etwas mehr. Oben in unserem Beispiel hatten wir „lol“ in unterschiedlichen Schreibweisen. Diese kann man mit Java 14 auch in eine Zeile schreiben, statt mit übereinander stehenden case
-Anweisungen. Ich habe hier zu noch einmal ein komplexeres Beispiel aufgebaut. Hier geht es darum, anhand des Alters die passende Begrifflichkeit für die Person festzulegen. Dafür gibt es natürlich extrem viele Möglichkeiten. Durch die Komma-Schreibweise der Fälle können wir die Zeilenanzahl deutlich reduzieren.
int age = 22;
switch (age) {
case 0,1,2,3,4,5,6,7,8,9,10,11,12:
System.out.println("Kind");
break;
case 13,14,15,16,17:
System.out.println("Teenager");
break;
default:
System.out.println("Erwachsen");
break;
}
An diesem Beispiel siehst du aber auch direkt ein Nachteil, wofür die Switch-Case-Kontrollstruktur nicht so gut geeignet ist: Es lassen sich keine Zahlenbereiche durch Vergleichsoperatoren definieren. Und wir können auch in dieser Kontrollstruktur keine Abfrage mache, ob age
wirklich größer 0 ist, so wäre ein negativer Wert erwachsen. Dadurch muss jede Zahl, die age
sein könnte, aufgelistet werden. Mit einer If-Anweisung hätte zum Beispiel durch den Vergleichsoperator <
definiert werden können, dass wenn age
kleiner als 13 ist, dass die Person ein Kind ist.
Nachdem wir nun die Basis kennengelernt haben, wollen wir noch einmal auf den Vorteil gegenüber einer if-else-Verkettung eingehen. Hier sieht man eigentlich direkt auf den ersten Blick, dass die Komplexität für denselben Ablauf deutlich steigt. Zudem kommt hinzu, dass man nicht mehrere Fälle ausführen könnte, wenn bereits ein Fall zustande kam. Das wichtige ist, dass der Einsatz von Switch-Case besonders effizient ist, wenn es viele Werte mit unterschiedlichen Fällen gibt, die aber eben zusammenhängend sind. Ansonsten ist häufig eine if-else-Verkettung die bessere Wahl.
if ( chatShort.equals("fyi") ) {
System.out.println("for your information / zu deiner Information");
} else if ( chatShort.equals("btw") ) {
System.out.println("by the way / übrigens");
} else if ( chatShort.equals(AFK) ) {
System.out.println("away from keyboard / nicht an der Tastatur");
} else if ( chatShort.equals("gn") ) {
System.out.println("good night / Gute Nacht");
} else if ( chatShort.equals("lol") || chatShort.equals("Lol") || chatShort.equals("LOL") ) {
System.out.println("laughing out loud / laut loslachen");
} else {
System.out.println("keine Abkürzung gefunden");
}
Seit Java 14 gibt es zu dem Doppelpunkt eine alternative Syntax mit einem Pfeil. Die Besonderheit hier ist, dass der Pfeil den Break ersetzt. Bedeutet, du brauchst nicht immer noch das Keyword break
zu setzen. Zusätzlich kann das Ganze jetzt nicht nur als Ausdruck, sondern auch als Anweisung verwendet werden. So kann ein Switch-Case-Ausdruck Werte zurückgegeben.
Unser Beispiel mit Pfeilen anstatt von Break und Doppelpunkt würde so aussehen. Das ist schon deutlich übersichtlicher. Welche Schreibweise du verwenden möchtest, ist dir überlassen. Wichtig ist, dass du bei dieser Variante nur eine Anweisung im Case haben kannst, sonst benötigst du noch einmal eine andere Syntax und das yield
Keyword.
switch ( chatShort ) {
case "fyi" -> System.out.println("for your information / zu deiner Information");
case "btw" -> System.out.println("by the way / übrigens");
case AFK -> System.out.println("away from keyboard / nicht an der Tastatur");
case "gn" -> System.out.println("good night / Gute Nacht");
case "lol", "Lol", "LOL" -> System.out.println("laughing out loud / laut loslachen");
default -> System.out.println("keine Abkürzung gefunden");
}
Nun machen wir aus der Switch-Case-Anweisung eine Switch-Case-Ausdruck. Der Unterschied ist, dass ein Ausdruck ein Wert zurückgibt. Weshalb wir nicht mehr mit Print arbeiten können, da diese kein Wert zurückgibt. Jetzt können wir dem jeweiligen Case einfach den passenden String zuordnen. Anschließende können wir diesen Wert eine Variable ausgeben. Du siehst außerdem, dass jetzt ein Semikolon am Ende des switch
benötigt wird, da es ein Ausdruck ist. Anschließende geben wir unseren Wert aus.
String hint = switch ( chatShort ) {
case "fyi" -> "for your information / zu deiner Information";
case "btw" -> "by the way / übrigens";
case AFK -> {
System.out.println("AFK Case");
yield "away from keyboard / nicht an der Tastatur";
}
case "gn" -> "good night / Gute Nacht";
case "lol", "Lol", "LOL" -> "laughing out loud / laut loslachen";
default -> "keine Abkürzung gefunden";
};
System.out.println(hint);
Zusätzlich gibt es noch den Fall, dass du trotz dieser Schreibweise mehrere Ausdrücke in einem Fall ausführen möchtest. Diese geht, wenn du ein Block mit geschweiften Klammern einsetzt, wie bei dem AFK Fall. Dort geben wir zusätzliche Informationen aus. Mittels dem yield
Keyword wird inzwischen definiert, was zurückgegeben wird, so kannst du dort noch komplexe Berechnungen oder Ähnliches anstellen. Eine Besonderheit gibt es noch. Wenn du mit dem Ausdruck arbeitest, musst du einen default
Wert angeben, sodass sichergestellt ist, dass es immer eine Rückgabe gibt. Ansonsten erhältst du den Fehler „not cover all possible input values“.
java: the switch expression does not cover all possible input values
Nun kannst du mal versuchen, einen kleinen Taschenrechner zu schreiben, mit welchem du 2 Integers mit einem definierten Operator verrechnen kannst. Ich habe mich für den Switch-Case-Ausdruck entschieden. Du kannst es bei deiner Lösung aber auch mal mit einer if-Anweisung versuchen. Letztlich musst du nur auf den jeweiligen Operator prüfen und a + b etc. rechnen. Poste deine Lösung gerne in die Kommentare!
int result = switch ( operand ) {
case '+' -> a + b;
case '-' -> a - b;
case '*', 'x' -> a * b;
case '/' -> a / b;
case '%' -> a % b;
default -> {
System.err.println("Undefined Operand");
yield 0;
}
};
System.out.println("Ergebniss:" + result);
Schau dir doch mal den Artikel zur Kommandozeileneingabe mittels der Scanner Klasse an. Damit kannst du dann eine interaktive Eingabe für deinen ersten Taschenrechner bauen.
Für die Verwendung von Switch-Case gibt es immer dann gute Gründe, wenn du einfache Werte und Fälle durchgehen willst, für die es viele Optionen gibt, ohne dass besondere Bedingungen noch benötigt werden. In diesen Fällen ist die Switch-Case-Anweisung oder auch der Ausdruck die bessere Wahl.
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 "Die Switch Case Anweisung & Ausdruck in Java"!