Home > Informatik > Begriffe und Konzepte > Switch-case-Anweisung

Switch-case-Anweisung

Die switch-case-Anweisung ist eine Kontrollstruktur, mit der ein Programm zwischen mehreren Alternativen unterscheiden kann. Sie eignet sich besonders dann, wenn ein Ausdruck auf Gleichheit mit verschiedenen konstanten Werten geprüft werden soll.

Im Gegensatz zu einer tief verschachtelten if-else-Anweisung ist die switch-case-Anweisung oft übersichtlicher, wenn viele Fälle unterschieden werden müssen.

Beispiel 1a
int x = 2;

switch (x)
{
   case 1:
      System.out.println("Eins"); break;
   case 2:
      System.out.println("Zwei"); break;
   case 3:
      System.out.println("Drei");
}

Diese switch-case-Anweisung wäre im Prinzip identisch mit folgender if-else-Anweisung:

int x = 2;

if (x == 1)
      System.out.println("Eins");
else if (x == 2)
      System.out.println("Zwei");
else if (x == 3)
      System.out.println("Drei");

Kürzer ist diese switch-case-Anweisung aus unserem Beispiel also nicht. Aber natürlich gibt es viele Fälle, wo die switch-break-Anweisung sehr viel kürzer und übersichtlicher sein kann als eine Reihe verschachtelter if-else-Anweisungen.

Beispiel 2a

Betrachten Sie dazu folgendes Beispiel aus der Folge 2 dieses Kurses:

switch (pMonth)
{
    case 4:
    case 6:
    case 9:
    case 11:
          return 30;

    case 2:
          if (isLeapYear())
              return 29;
          else
              return 28;

    default:
          return 31;
  }

Hier wird der Monat pMonth überprüft, wie viele Tage er maximal hat. Die Monate 4, 6, 9 und 11 haben 30 Tage, der Monat 2 28 oder 29 Tage. Alle anderen Monate (und das ist dann der default-Fall) haben 31 Tage.

An sich dient der default-case als globales "else" in einer switch-case-Anweisung. Falls alle anderen Fälle nicht zutreffen, dann wird die Anweisung im default-Zweig ausgeführt.

In diesem Beispiel wird die default-Anweisung "missbraucht", um den häufigsten bzw. wahrscheinlichsten Fall zu berücksichtigen. Die meisten Monate haben nämlich 31 Tage. Fall ein Monat also nicht 2, 4, 6, 9 oder 11 ist, ist die maximale Tageszahl 31.

Beispiel 1b: Notwendigkeit von break
int x = 2;

switch (x)
{
   case 1:
      System.out.println("Eins");
   case 2:
      System.out.println("Zwei");
   case 3:
      System.out.println("Drei");
}

Dieses Beispiel sieht so ähnlich aus wie das erste Beispiel. Aber das Schlüsselwort "break" fehlt hier am Ende der case-Fälle.

Man würde eigentlich erwarten, dass hier "Zwei" ausgegeben wird, weil ja der case 2 zutrifft. Das ist aber nicht der Fall. Es wird "Zwei" und "Drei" ausgegeben.

Der break-Befehl hat zur Folge, dass die switch-case-Anweisung sofort abgebrochen wird. Die restlichen Fälle werden dann gar nicht mehr überprüft.

Da hier kein break am Ende von case 2 steht, wird case 3 ausgeführt und "Drei" ausgegeben.

Beispiel 2b:

Schauen wir uns jetzt noch einmal das Beispiel 2a an:

switch (pMonth)
{
    case 4:
    case 6:
    case 9:
    case 11:
          return 30;

    case 2:
          if (isLeapYear())
              return 29;
          else
              return 28;

    default:
          return 31;
  }

Hier stehen auch keine break-Anweisungen. Die switch-case-Anweisung funktioniert dennoch fehlerfrei, weil die return-Befehle die Rolle des break-Befehls übernehmen. Wenn einer der Fälle pMonth == 4, 6, 9 oder 11 eintritt, wird return 30 ausgeführt. Der case 2 und der default-case werden dann gar nicht mehr untersucht.

Das Fall-Trough-Phänomen

Bei den Fällen 4, 6, 9 und 11 setzt man also das sogenannte "Fall-Through" (das Hinunterfallen) bewusst als Feature ein. Da hinter case 4 kein break steht, wird automatisch case 6 untersucht. Auch hier gibt es kein break, daher wird sofort mit case 9 und schließlich mit case 11 weitergemacht. Erst hier ist Schluss mit dem Hinunterfallen, es wird 30 zurückgegeben.

Switch-Ausdrücke

Betrachten Sie folgenden Quelltext:

    public int getMaxDay(int pMonth, int pYear)
    {
        return switch (pMonth)
        {
            case 4, 6, 9, 11 -> 30;
            case 2 -> isLeapYear() ? 29 : 28;
            default -> 31;
        };
    } 

Es handelt sich hier um eine moderne Form des switch-Befehls, die seit Java 17 erlaubt ist. Man nennt sie auch Switch-Ausdruck oder Switch-Expression, weil der switch-Befehl hier einen Wert zurückliefert.

Der ganze Switch-Ausdruck ist im Grund ähnlich wie der Aufruf einer sondierenden Methode, die einen Wert zurückliefert. Mit Hilfe des return-Befehls kann die Methode getMaxDay() das Ergebnis dieser switch-expression zurückliefern.

Der -> Operator ist hier neu, er bestimmt quasi, welchen Wert die switch-expression hat bzw. welcher Wert zurückgegeben werden soll.

Neu - aber nicht erst seit Java 17 - ist die besondere Form der if-else-Anweisung..

Statt

if (isLeapYear()
   return 29;
else
   return 28;

Schreibt man hier kurz:

-> isLeapYear() ? 29 : 28;

Auf das "if" verzichtet man hier ganz, das "then" (das ja auch in der regulären if-else-Anweisung nicht auftaucht) wird durch das Fragezeichen ersetzt, und das "else" durch den Doppelpunkt.

Quellen:

  1. Lahres et al.: Objektorientierte Programmierung, Rheinwerk Computing 2021.
  2. Barnes, Kölling: Java lernen mit BlueJ - Objects first. Pearson-Verlag 2019.
  3. Ullenboom: Java ist auch eine Insel, Rheinwerk Computing 2023.