Switch-Statement, Typ-Prüfung mit "instanceof"
1. Klassisches Switch-Statement
Neben der Fallunterscheidung mit if { … } else if (..) { … } else if (..) { … } else { … }
gibt es in vielen Programmiersprachen auch das switch
-Statement.
Dieses vergleicht einen gegebenen Wert mit mehreren fixen case
-Werten und führt den danach stehenden Code aus, bis ein break
angetroffen wird.
Mögliche Datentypen sind byte
, short
, char
, int
, die dazugehörigen Wrapper-Klassen (Byte
, Short
, Character
, Integer
), String
sowie Enumerationen (enum).
Hier einige Beispiele (mit char, int, String, enum):
public String switchCharDemo(char ch) {
String zeichenArt;
char chLower = Character.toLowerCase(ch);
switch (chLower) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
zeichenArt = "vokal";
break;
case 'ä':
case 'ö':
case 'ü':
zeichenArt = "umlaut";
break;
default: // optional, wie 'else' bei 'if'
zeichenArt = "sonstig";
}
return zeichenArt;
}
public String switchIntDemo(int val) {
String teilbarkeitsRegel = "Teilbarkeitsregel für " + val + ": ";
switch (val) {
case 2:
teilbarkeitsRegel += "wenn letzte Ziffer 0, 2, 4, 6, 8";
break;
case 3:
teilbarkeitsRegel += "wenn Ziffernsumme durch 3 teilbar";
break;
case 4:
teilbarkeitsRegel += "wenn letzte 2 Ziffern durch 4 teilbare Zahl";
break;
case 5:
teilbarkeitsRegel += "wenn letzte Ziffer 0 oder 5";
break;
case 6:
teilbarkeitsRegel += "wenn durch 2 und durch 3 teilbar";
break;
case 10:
teilbarkeitsRegel += "wenn letzte Ziffer 0";
break;
default:
teilbarkeitsRegel = "keine Teilbarkeitsregel für " + val + " vorhanden";
} // weitere Regeln für 7, 8, 9, 11, 12, 15, 25, ..., deren 10-fache, ...
return teilbarkeitsRegel;
}
public static String switchStringDemo(String monat) {
String info = "Monat ";
switch (monat) {
case "Jänner":
case "Januar": // Ausnützen des fehlenden 'break;'
case "März":
case "Mai":
case "Juli":
case "August":
case "Oktober":
case "Dezember":
info += monat + " hat 31 Tage";
System.out.println(info);
break; // bei Vergessen wird Code darunter weiter abgearbeitet, an 'info' angehängt, ...
case "Februar":
case "Feber":
info += monat + " hat 28 oder 29 (Schaltjahr) Tage";
System.out.println(info);
break; // nicht vergessen!
case "April":
case "Juni":
case "September":
case "November":
info += monat + " hat 30 Tage";
System.out.println(info);
break; // nicht vergessen!
default:
info += "kein gültiger Monat: '" + monat + "'";
System.out.println(info);
}
return info;
}
public enum Wochentag {
MONTAG, DIENSTAG, MITTWOCH, DONNERSTAG, FREITAG, SAMSTAG, SONNTAG
}
// Aufruf z.B. mit: switchEnumDemo(ÄußereKlasse.Wochentag.SAMSTAG);
public String switchEnumDemo(Wochentag wochentag) {
String info = "Arbeitstag ";
switch (wochentag) {
case MONTAG:
info += "Freitag";
break; // bei Vergessen wird Code darunter weiter
// abgearbeitet, an 'info' angehängt, ...
case DIENSTAG:
info += "Dienstag";
break;
case MITTWOCH:
info += "Mittwoch";
break;
case DONNERSTAG:
info += "Donnerstag";
case FREITAG:
info += "Freitag";
break;
default:
info = "Wir haben Wochenende!";
}
return info;
}
2. Neuer Switch-Ausdruck
Mit Java-14 (März 2020) final (mit Änderungen zu "Preview" in Java-12) ist eine erweiterte Form von switch
verfügber – mit folgenden Eckpunkten:
-
es ist nun kein Statement ( = Anweisung) mehr, sondern wurde zu einem Expression ( = Ausdruck) erweitert – hat also jetzt einen Rückgabewert und kann somit überall dort direkt (also ohne Umweg über Zuweisungen an eine Variable, die hinterher benutzt wird) eingesetzt werden, wo ein Element des passenden Typs benötigt wird.
-
es ist mit einer zusätzlichen, neuen Syntax nicht mehr nötig, das vergessens-gefährliche
break
einzusetzen.
public static String switchNewExpressionDemo(String monat) {
String info = "Monat " + switch (monat) {
case "Jänner", "Januar", "März", "Mai", "Juli", "August", "Oktober", "Dezember" -> {
String txt = monat + " hat 31 Tage";
System.out.println(txt); // Kontroll-Ausgabe
yield txt; // Rückgabewert, der an 'info' angehängt wird
}
case "Februar", "Feber" -> {
String txt = monat + " hat 28 oder 29 (Schaltjahr) Tage";
System.out.println(txt);
yield txt;
}
case "April", "Juni", "September", "November" -> {
String txt = monat + " hat 30 Tage";
System.out.println(txt);
yield txt;
}
default -> {
String txt = "kein gültiger Monat: '" + monat + "'";
System.out.println(txt);
yield txt;
}
};
return info;
}
3. Typ-Prüfung mit "instanceof" und weitere Möglichkeiten
Mit Java 16 (März 2021) final (seit Java-14 als "Preview") besteht die Möglichkeit, gleich eine Variable für den richtig getypten Zugriff mitzugeben. Das erlaubt es, den früher nötigen Code:
Object obj = new Schueler("Evi", "1AHIF"); // gleich wie unten
if (obj instanceof Schueler) { // mühsam: 1x Typ 'Schueler', 1x 'obj'
Schueler s = (Schueler) obj; // danach: 2x Typ 'Schueler', 1x 'obj' ...
System.out.println("Klasse: " + s.getKlasse());
///...
}
zu vereinfachen auf:
Object obj = new Schueler("Evi", "1AHIF"); // gleich wie oben
if (obj instanceof Schueler s) { // kompakter: 1x Typ 'Schueler', 1x obj ...
System.out.println("Klasse: " + s.getKlasse());
///...
}
4. Typ-Prüfung mit dem Class-Object
Links dazu: JEP 305: Pattern Matching for instanceof (Preview) … 15.6.2021, 08:12:08