Java Pattern Matching
Simplify instanceof checks and switch statements with pattern matching (Java 16+)
java (16+)
2025-11-03
pattern-matching
switch
instanceof
java16
Description
Pattern matching simplifies common coding patterns by combining type checking and casting into a single operation. It reduces boilerplate code and makes programs more readable and less error-prone.
Key Features
- Pattern matching for instanceof: Automatically casts after type check
- Pattern matching for switch: Use patterns in switch expressions
- Type patterns: Match against types and bind variables
- Guarded patterns: Add conditions to pattern matches
Benefits
- Less boilerplate: No explicit casting needed
- Safer code: Compiler ensures type safety
- More readable: Clear intent in code
- Exhaustiveness checking: Compiler can verify all cases handled
Evolution
- Java 14: Pattern matching for instanceof (preview)
- Java 16: Pattern matching for instanceof (standard)
- Java 17: Pattern matching for switch (preview)
- Java 19: Pattern matching for switch (standard)
- Java 21: Record patterns, pattern matching improvements
Code
public class PatternMatchingUtils { // Pattern matching with instanceof (Java 16+) public static String process(Object obj) { if (obj instanceof String str) { return "String: " + str.toUpperCase(); } else if (obj instanceof Integer num) { return "Integer: " + (num * 2); } else if (obj instanceof Number num) { return "Number: " + num.doubleValue(); } return "Unknown type"; } // Pattern matching with guarded patterns public static String processWithGuard(Object obj) { if (obj instanceof String str && str.length() > 5) { return "Long string: " + str; } else if (obj instanceof String str) { return "Short string: " + str; } return "Not a string"; } // Pattern matching in switch (Java 17+) public static String processWithSwitch(Object obj) { return switch (obj) { case String str -> "String: " + str; case Integer i -> "Integer: " + i; case Double d -> "Double: " + d; case null -> "Null value"; default -> "Unknown: " + obj.getClass().getSimpleName(); }; } // Pattern matching with sealed classes public static double calculateArea(Shape shape) { return switch (shape) { case Circle c -> Math.PI * c.radius() * c.radius(); case Rectangle r -> r.width() * r.height(); case Triangle t -> 0.5 * t.base() * t.height(); }; } // Pattern matching with records public static String describe(Person person) { return switch (person) { case Person(String name, int age) when age < 18 -> name + " is a minor"; case Person(String name, int age) when age >= 65 -> name + " is a senior"; case Person(String name, int age) -> name + " is an adult"; }; }}
// Old way (before pattern matching)Object obj = "Hello";if (obj instanceof String) { String str = (String) obj; // Explicit cast System.out.println(str.length());}// New way with pattern matching (Java 16+)Object obj2 = "Hello";if (obj2 instanceof String str) { // str is automatically cast and available System.out.println(str.length());}// Pattern matching with conditionsObject obj3 = "Hello World";if (obj3 instanceof String s && s.length() > 5) { System.out.println("Long string: " + s);}// Pattern matching in switch (Java 17+)Object value = 42;String result = switch (value) { case String s -> "String: " + s; case Integer i -> "Integer: " + i; case Double d -> "Double: " + d; case null -> "Null"; default -> "Unknown";};// Pattern matching with sealed classesShape shape = new Circle(5.0);double area = switch (shape) { case Circle c -> Math.PI * c.radius() * c.radius(); case Rectangle r -> r.width() * r.height(); case Triangle t -> 0.5 * t.base() * t.height();};// Pattern matching with recordsrecord Person(String name, int age) {}Person person = new Person("Alice", 25);String description = switch (person) { case Person(String name, int age) when age < 18 -> name + " is a minor"; case Person(String name, int age) -> name + " is " + age + " years old";};// Nested pattern matchingrecord Point(int x, int y) {}record Line(Point start, Point end) {}Line line = new Line(new Point(0, 0), new Point(10, 10));String lineInfo = switch (line) { case Line(Point(int x1, int y1), Point(int x2, int y2)) -> "Line from (" + x1 + "," + y1 + ") to (" + x2 + "," + y2 + ")";};
Comments
No comments yet. Be the first to comment!
Please login to leave a comment.