Java密封接口需用sealed+permits声明,且所有许可实现类必须显式标注final/sealed/non-sealed;permits列表须为同模块或可访问的具体类名,大小写与包路径严格匹配,并需在module-info.java中正确配置exports和requires。

Java 中用 sealed 关键字限制接口只能被特定类实现,核心是两步:接口声明时加 sealed 和 permits,所有被允许的实现类必须显式声明 final、sealed 或 non-sealed。
密封接口必须带 permits 列表
不能只写 public sealed interface X { }——这会编译失败,报错“sealed type must have a permits clause”。permits 后面必须紧跟**已存在、可访问、同模块(或同包)的具体类名**,不能是字符串、通配符或未定义的类型。
public sealed interface PaymentStrategy permits CreditCardPayment, AlipayPayment { }- 类名大小写、包路径要完全匹配;如果类在其他包,需确保该包已被模块
exports - 多个类用逗号分隔,末尾不加逗号,也不加花括号
每个许可类必须声明自身继承策略
哪怕你只想让一个类实现接口,这个类也**不能默认自由继承**——它必须用 final、sealed 或 non-sealed 明确表态,否则编译器拒绝:“class X is not allowed to extend sealed interface Y”。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
-
public final class CreditCardPayment implements PaymentStrategy { ... }(最常用,彻底封闭) -
public sealed class AlipayPayment implements PaymentStrategy permits AlipayMiniAppPayment { ... }(自身也密封,再限制子类) -
public non-sealed class WechatPayment implements PaymentStrategy { ... }(开放继承,但仅限当前模块内)
注意模块与编译范围
密封关系在编译期强制校验,依赖源码可见性。如果接口和实现类不在同一模块,需在 module-info.java 中正确配置:
立即学习“Java免费学习笔记(深入)”;
- 接口所在模块要用
exports pkg.name;导出接口所在包 - 实现类所在模块要用
requires interface.module.name; - 所有相关类最好一起编译,避免 “class not found” 类错误
常见错误和绕不开的细节
很多问题不是语法写错,而是结构没对齐:
- 把
permits当成运行时白名单——它只管编译期直接实现,反射仍可能绕过(但会触发安全异常) - 接口
extends了另一个接口:若父接口是密封的,子接口也必须是sealed,且permits需重新明确列出允许的实现者 - 嵌套类(如
static final class Impl)也要加final等修饰符,不能省略

















