Switching Up Java: Unpacking Pattern Matching in Java 21

Photo of Luqman Saeed by Luqman Saeed

Pattern Matching for switch, introduced in Java 21 via JEP 441, marks a significant enhancement to the Java programming language, offering a more expressive and compact way to handle complex decision blocks. This feature extends the existing switch construct by allowing patterns in case labels, thus facilitating more concise, readable, and safe code when dealing with multi-way comparisons​​.

History and Evolution

The journey towards this feature began as early as JDK 17 with JEP 406, and it saw refinements across subsequent versions (JDKs 18 through 20) via JEPs 420, 427, and 433. The finalization of this feature in JDK 21 came after these series of previews and community feedback, which helped in making necessary refinements, including the removal of parenthesized patterns deemed to lack sufficient value and the inclusion of qualified enum constants as case constants in switch expressions and statements​.

Goals

The primary goals of Pattern Matching for switch as outlined in JEP 441 are:

  1. Enhancing the expressiveness and applicability of switch expressions and statements by allowing patterns in case labels.
  2. Relaxing the historical null-hostility of switch when desired.
  3. Increasing the safety of switch statements by requiring that pattern switch statements cover all possible input values.
  4. Ensuring that all existing switch expressions and statements continue to compile with no changes and execute with identical semantics​​.

Motivation

Before the introduction of Pattern Matching for switch, we often found ourselves entangled in chains of if-else tests when comparing a variable against multiple alternatives. This was because the existing switch construct was limited to checking for exact equality against constants and could only cater to a few types like integral primitive types (excluding long), their corresponding boxed forms, enum types, and String. JEP 441 addresses these limitations by extending switch statements and expressions to work on any type and allow case labels with patterns, thus making code clearer, more reliable, and optimizable​​.

The examples below show how the new pattern matching construct in Java 21 simplifies code readability for decision making. First let's consider the following Shape class:

enum ShapeType { CIRCLE, RECTANGLE, TRIANGLE }

abstract class Shape {
    public ShapeType type;
   
}

class Circle extends Shape {
    public double radius;
    
    public Circle() {
        this.type = ShapeType.CIRCLE;
    }
   
}

class Rectangle extends Shape {
    public double width, height;
    
    public Rectangle() {
        this.type = ShapeType.RECTANGLE;
    }
   
}

class Triangle extends Shape {
    public double base, height;
    
    public Triangle() {
        this.type = ShapeType.TRIANGLE;
    }
   
}

To make a decision based on the ShapeType of a given shape, the classic switch statement would look as follows:


public double calculateArea(Shape shape) {
    switch (shape.type) {
        case CIRCLE:
            Circle c = (Circle) shape;
            return Math.PI * c.radius * c.radius;
        case RECTANGLE:
            Rectangle r = (Rectangle) shape;
            return r.width * r.height;
        case TRIANGLE:
            Triangle t = (Triangle) shape;
            return 0.5 * t.base * t.height;
        default:
            throw new IllegalArgumentException("Unknown shape type!");
    }
}

Clearly there is a lot of verbosity in there. This is not only tedious to write, but more importantly it's cognitively tasking to read. The switch expression using the enhanced pattern matching in Java 21 is as follows:



public 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;
        default -> throw new IllegalArgumentException("Unknown shape!");
    };

}

As you can see, the new construct is much more compact, easy to write and more importantly, easy to read. At the first glance you can tell the intent of the code with less cognitive effort. 

As the Java Language continues to get refined, the introduction of Pattern Matching for switch in Java 21 through JEP 441 is a testament to the language's evolution towards more expressive and efficient coding paradigms. By alleviating the need for verbose code and explicit type casting, this feature not only simplifies the syntax but also enhances code readability and maintainability.

The journey from the classic switch statement to the enriched pattern matching in Java 21 illustrates the ongoing commitment to making Java more adaptable and robust. As developers, embracing these advancements allows us to write cleaner, safer, and more descriptive code, thereby elevating the overall programming experience in the Java ecosystem. Never been a better time to be a Java developer!

Interested in more Java 21 content?

Fully managed Jakarta EE Cloud Deployment. ✅Handles Kubernetes for you.✅ 15 day free trial available.✅

Payara Cloud.

TRY FREE.

Comments