sealed和permits是Java 17引入的封闭类特性,用于显式限定可继承父类的子类集合;父类用sealed声明并用permits列出直接子类,各子类须声明final/sealed/non-sealed继承策略,编译器强制校验。

sealed 和 permits 是 Java 17 引入的特性(JEP 409),用于显式控制类的继承关系,实现“封闭类层次结构”——即只允许指定的几个类继承某个父类,其他任何类都不行。
用 sealed 声明封闭父类
被 sealed 修饰的类必须明确列出哪些子类可以继承它,否则编译报错。它不能是 final,也不能是 non-sealed(除非在模块内被重新打开)。
写法示例:
public sealed class Shape permits Circle, Rectangle, Triangle { }用 permits 明确列出许可的子类
permits 后面跟的是直接子类名(不是全限定名),这些类必须与 sealed 父类在同一个模块中(或同一文件中,适用于简单场景)。每个被许可的子类还必须用以下三者之一声明其继承意图:
- final:彻底禁止进一步继承(推荐用于叶子类)
- sealed:自身也封闭,可继续用 permits 限制下级
- non-sealed:主动开放继承,任何类都可继承它(慎用,会破坏封闭性)
示例:
public final class Circle extends Shape { }public sealed class Rectangle extends Shape permits RoundedRectangle { }
public non-sealed class RoundedRectangle extends Rectangle { }
编译器强制执行继承边界
一旦父类声明为 sealed + permits,任何未在 permits 列表中的类尝试继承它,编译器立即报错:
error: class Square is not allowed to extend sealed class Shape同样,如果 permits 中列出的子类没有用 final / sealed / non-sealed 明确声明继承策略,也会编译失败。
典型使用场景
- 建模有限且稳定的类型集合,如表达式树(Literal、BinaryOp、UnaryOp)、协议消息体、状态枚举替代方案
- 配合 switch 表达式做详尽模式匹配(Java 17+ 的 sealed 类可被 switch exhaustive 检查)
- 防止意外继承导致的逻辑泄漏或破坏封装(比仅靠文档约定更可靠)

















