Pattern Matching im switch-Statement ist seit Java 21 ein vollwertiges Feature, das die Ausdruckskraft und Lesbarkeit von Code deutlich erhöht. Es ermöglicht, dass case-Labels nicht nur konstante Werte, sondern auch Typmuster und Bedingungen enthalten können, wodurch komplexe Entscheidungslogik kompakter und sicherer gestaltet werden kann.
Mit Pattern Matching im switch lassen sich beispielsweise unterschiedliche Objektarten direkt im switch-Statement abfragen und verarbeiten, ohne vorheriges instanceof und explizites Casting.
Neu ist auch, dass der switch jetzt explizit auf null-Werte prüfen kann, indem ein case null definiert wird, was die Behandlung von Nullwerten vereinfacht.
Ein Beispiel mit Pattern Matching in switch:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
package de.wenzlaff.twrente; /** * Verwendung von Record Patterns mit switch. * * Mit JEP 440 https://openjdk.org/jeps/440 in Java 21 eingeführt * * @author Thomas Wenzlaff */ public class StartJava21Switch { record Point(int i, int j) { } enum Color { RED, GREEN, BLUE; } public static void main(String[] args) { typeTester(Color.RED); Point punkt = new Point(4, 2); typeTester(punkt); typeTester(null); // geht auch typeTester("null"); // String geht auch, aber nicht im null case typeTester(Long.MAX_VALUE); // default Zweig } static void typeTester(Object obj) { switch (obj) { case null -> System.out.println("null"); case String s -> System.out.println("String"); case Color c -> System.out.println("Color: " + c.toString()); case Point p -> System.out.println("Record class: " + p.toString()); case int[] ia -> System.out.println("Array of ints of length" + ia.length); default -> System.out.println("Default, nicht behandelt: " + obj); } } } |
Durch die Einführung von sogenannten Guarded Patterns mit dem when-Schlüsselwort lassen sich zudem zusätzliche Bedingungen innerhalb eines case formulieren. Insgesamt führt Pattern Matching im switch zu kürzerem, verständlicherem und weniger fehleranfälligem Java-Code.
Noch ein Beispiel:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
package de.wenzlaff.twrente; /** * Verwendung von Record Patterns mit switch. * * Mit JEP 440 https://openjdk.org/jeps/440 in Java 21 eingeführt * * @author Thomas Wenzlaff */ public class StartJava21Switch { record Point(int i, int j) { } enum Color { RED, GREEN, BLUE; } public static void main(String[] args) { typeTester(Color.RED); Point punkt = new Point(4, 2); typeTester(punkt); typeTester(null); // geht auch typeTester("null"); // String geht auch, aber nicht im null case typeTester(Long.MAX_VALUE); // default Zweig // und für Guarded Patterns mit dem when-Schlüsselwort checkNumber(Integer.valueOf(42)); checkNumber(Integer.valueOf(-42)); checkNumber(Long.valueOf(42)); //checkNumber(null); // geht nicht, wirft NullPointerException } static void checkNumber(Object obj) { switch (obj) { case Integer i when i > 0 -> System.out.println("Positive Zahl"); case Integer i when i < 0 -> System.out.println("Negative Zahl"); case Integer i -> System.out.println("Null"); default -> System.out.println("Kein Integer, sondern " + obj); } } static void typeTester(Object obj) { switch (obj) { case null -> System.out.println("null"); case String s -> System.out.println("String"); case Color c -> System.out.println("Color: " + c.toString()); case Point p -> System.out.println("Record class: " + p.toString()); case int[] ia -> System.out.println("Array of ints of length" + ia.length); default -> System.out.println("Default, nicht behandelt: " + obj); } } } |
Ergebnis:
1 2 3 4 5 6 7 8 |
Color: RED Record class: Point[i=4, j=2] null String Default, nicht behandelt: 9223372036854775807 Positive Zahl Negative Zahl Kein Integer, sondern 42 |