
Sealed interface ใน Java 17: ปิดชุดชนิดย่อยและบังคับพฤติกรรมร่วม
น้องกายEngineering
เวลาโมเดลผลลัพธ์มีแค่ไม่กี่แบบ เช่น สำเร็จ / รอ / ล้มเหลว เราอยากให้คอมไพเลอร์รู้ว่ามีชนิดย่อยใดเข้าระบบได้บ้าง sealed ช่วยปิดขอบเขตนี้ครับ
ตั้งแต่ Java 17 อินเทอร์เฟซหรือคลาสประกาศ sealed แล้วระบุ permits ได้เฉพาะชนิดที่ยอมรับ ชนิดอื่นขยายไม่ได้ตามใจ เอกสารอยู่ที่ Oracle sealed classes and interfaces ส่วน record patterns ใน switch ของตัวอย่างเก่าต้องใช้ Java 21 จึงไม่ควรติดป้ายว่าเป็นโค้ด Java 17
public class Main {
sealed interface Result permits Ok, Wait, Err {
String describe();
}
record Ok(String value) implements Result {
public String describe() { return "ok:" + value; }
}
record Wait(int seconds) implements Result {
public String describe() { return "wait:" + seconds; }
}
record Err(String message) implements Result {
public String describe() { return "err:" + message; }
}
static String describe(Result r) {
return r.describe();
}
public static void main(String[] args) {
if (!"ok:hi".equals(describe(new Ok("hi")))) throw new AssertionError();
if (!"wait:3".equals(describe(new Wait(3)))) throw new AssertionError();
if (!"err:x".equals(describe(new Err("x")))) throw new AssertionError();
System.out.println("ok");
}
}
Recap
- ใช้ sealed เมื่อชุดชนิดย่อยปิดและรู้จักครบ
- บน Java 17 วาง method contract เมื่อทุกชนิดต้องมีพฤติกรรมเดียวกัน
- ใช้ exhaustive pattern switch เมื่อ baseline ของทีมเป็น Java 21 ขึ้นไป
- อย่า sealed ทุกอย่าง — เปิดให้ขยายได้ถ้าโดเมนยังไม่นิ่ง