Java Sealed Classes และ Pattern Matching (Java 17+)

#java13 เม.ย. 2569

Sealed Classes คืออะไร

Sealed Classes (Java 17+) ช่วยให้กำหนดได้ว่า class ใดบ้างที่สามารถ extend ได้ ทำให้ type hierarchy ชัดเจนและปลอดภัยขึ้น

Sealed Class

// กำหนดว่า Shape มีได้แค่ 3 subclass
public sealed class Shape
    permits Circle, Rectangle, Triangle {}

public final class Circle extends Shape {
    private final double radius;
    public Circle(double radius) { this.radius = radius; }
    public double radius() { return radius; }
}

public final class Rectangle extends Shape {
    private final double width, height;
    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }
    public double width() { return width; }
    public double height() { return height; }
}

public non-sealed class Triangle extends Shape {
    // non-sealed อนุญาตให้ extend ต่อได้
}

Pattern Matching กับ switch

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;  // simplified
    };
    // ไม่ต้อง default เพราะ compiler รู้ว่าครบทุก case
}

Pattern Matching กับ instanceof

// ก่อน Java 16
if (obj instanceof String) {
    String s = (String) obj;  // ต้อง cast
    System.out.println(s.length());
}

// Java 16+ Pattern Matching
if (obj instanceof String s) {
    System.out.println(s.length());  // ไม่ต้อง cast
}

// กับ condition
if (obj instanceof String s && s.length() > 5) {
    System.out.println("Long string: " + s);
}

Sealed Interface

public sealed interface Result<T>
    permits Result.Success, Result.Failure {

    record Success<T>(T value) implements Result<T> {}
    record Failure<T>(String error) implements Result<T> {}

    static <T> Result<T> success(T value) {
        return new Success<>(value);
    }

    static <T> Result<T> failure(String error) {
        return new Failure<>(error);
    }
}

// ใช้งาน
Result<User> result = userService.findUser(1);
String message = switch (result) {
    case Result.Success<User> s -> "พบ user: " + s.value().getName();
    case Result.Failure<User> f -> "Error: " + f.error();
};

Guarded Patterns

Object obj = 42;
String description = switch (obj) {
    case Integer i when i < 0 -> "ลบ";
    case Integer i when i == 0 -> "ศูนย์";
    case Integer i -> "บวก: " + i;
    case String s -> "String: " + s;
    default -> "อื่นๆ";
};

สรุป

Sealed Classes + Pattern Matching ทำให้ Java มี algebraic data types คล้าย Kotlin/Scala ช่วยให้เขียน type-safe code ที่ compiler ตรวจสอบความครบถ้วนได้ครับ