javaintermediate

Sealed Classes and Pattern Matching

Use sealed interfaces with pattern matching switch for type-safe, exhaustive algebraic data types.

java
// Sealed interface — only permitted subtypes
public sealed interface Shape
    permits Circle, Rectangle, Triangle {
    double area();
}

record Circle(double radius) implements Shape {
    public double area() { return Math.PI * radius * radius; }
}

record Rectangle(double width, double height) implements Shape {
    public double area() { return width * height; }
}

record Triangle(double base, double height) implements Shape {
    public double area() { return 0.5 * base * height; }
}

// Pattern matching with switch (Java 21+)
class ShapeProcessor {
    static String describe(Shape shape) {
        return switch (shape) {
            case Circle c when c.radius() > 10 ->
                "Large circle with area " + c.area();
            case Circle c ->
                "Circle with radius " + c.radius();
            case Rectangle r when r.width() == r.height() ->
                "Square with side " + r.width();
            case Rectangle r ->
                "Rectangle " + r.width() + "x" + r.height();
            case Triangle t ->
                "Triangle with base " + t.base();
        }; // exhaustive — no default needed
    }

    public static void main(String[] args) {
        List<Shape> shapes = List.of(
            new Circle(5), new Rectangle(4, 4), new Triangle(3, 6)
        );
        shapes.forEach(s -> System.out.println(describe(s)));

        double totalArea = shapes.stream()
            .mapToDouble(Shape::area)
            .sum();
        System.out.printf("Total area: %.2f%n", totalArea);
    }
}

Use Cases

  • Type-safe state machines and event handling
  • Algebraic data types for domain modeling
  • Exhaustive pattern matching in business rules

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.