java 17的密封类通过sealed关键字和permits子句精确控制继承权限,要求子类显式声明final/sealed/non-sealed、同模块可见、且必须在permits中列出并正确继承;它与switch模式匹配协同实现编译期穷尽性检查。

Java 17 引入了密封类(sealed classes),用于显式控制哪些类可以继承某个父类或实现某个接口。它不是“禁止继承”,而是“精确授权继承”——你必须明确列出所有被允许的直接子类,其他类一律无法扩展它。
什么是密封类?核心规则有哪些
密封类通过 sealed 关键字声明,并配合 permits 子句指定可继承的子类列表。要满足三个硬性要求:
- 声明为 sealed 的类必须是 explicitly final、sealed 或 non-sealed 三者之一(即每个直接子类都必须明确自己的继承策略)
- permits 列表中的类必须与密封类在同一个模块中(如果是单文件编译,则必须在同一文件或已编译可见)
- 所有 permits 中列出的类,必须用 extends 或 implements 显式继承/实现该密封类,且自身也需声明继承策略
如何正确定义一个密封类
以下是一个典型示例:用密封类建模不同类型的表达式节点:
public sealed interface Expr
permits ConstantExpr, BinaryExpr, UnaryExpr {}
<p>final class ConstantExpr implements Expr {
public final double value;
public ConstantExpr(double value) { this.value = value; }
}</p><p>sealed class BinaryExpr implements Expr
permits AddExpr, MulExpr {}</p><p>final class AddExpr extends BinaryExpr { /<em> ... </em>/ }
final class MulExpr extends BinaryExpr { /<em> ... </em>/ }</p><p>non-sealed class UnaryExpr implements Expr {} // 允许进一步扩展</p>
注意:BinaryExpr 是 sealed 但不是 final,所以它自己还能有子类;而 ConstantExpr 是 final,彻底封闭;UnaryExpr 标记为 non-sealed,表示开放后续继承 —— 这种组合非常灵活。
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
为什么不能只写 sealed 不写 permits
编译器需要静态可知所有合法子类型,因此 permits 是 mandatory 的。下面写法会编译失败:
public sealed interface Expr {} // ❌ 缺少 permits
如果想让子类分散在多个文件中,permits 列表仍需包含它们的全限定名,且这些类必须已存在或能被编译器解析到。IDE 通常会在你添加新子类时提示更新 permits 列表。
密封类和模式匹配(switch)天然搭配
密封类最强大的协同特性是 Java 17+ 的 switch 表达式对密封类的穷尽性检查:
double eval(Expr e) {
return switch (e) {
case ConstantExpr c -> c.value;
case AddExpr a -> eval(a.left) + eval(a.right);
case MulExpr m -> eval(m.left) * eval(m.right);
case UnaryExpr u -> -eval(u.expr); // 编译器知道已覆盖全部 permitted 子类
};
}
只要 Expr 是 sealed 且所有子类都在 permits 中,编译器就能确认 switch 已穷尽所有可能,无需 default 分支 —— 这极大提升类型安全与可维护性。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










