Lesson 5 / 38

Records, Sealed Types & Pattern Matching

Write concise immutable data carriers with records, close a type hierarchy with sealed, and destructure them in exhaustive switch pattern matching.

Records

A record generates a canonical constructor, private final fields, accessors, equals, hashCode, and toString. It's the right choice for immutable value objects and DTOs.

record Point(int x, int y) {
    Point {                       // compact constructor: validation
        if (x < 0 || y < 0) throw new IllegalArgumentException();
    }
}
var p = new Point(3, 4);
p.x();   // 3

Sealed + switch patterns

A sealed interface lists its only permitted implementations, so a switch over them can be exhaustive with no default, and record patterns destructure in place.

sealed interface Shape permits Circle, Rect {}
record Circle(double r) implements Shape {}
record Rect(double w, double h) implements Shape {}

double area(Shape s) {
    return switch (s) {
        case Circle(double r) -> Math.PI * r * r;
        case Rect(double w, double h) -> w * h;
    };
}