non-sealed 是密封类的显式设计选择,主动放弃类型穷尽性保障;其导致 switch 必须加 default,且新增子类无法被编译器枚举,易引发运行时逻辑遗漏。

密封类中混用 non-sealed 本身不是“编译器漏洞”,而是设计意图的显式体现——它主动放弃该分支的类型穷尽性保障。真正需要防范的,是**误用 non-sealed 破坏整体穷尽性预期**,导致 switch 表达式无法校验、逻辑遗漏悄然潜入。
明确 non-sealed 的语义后果
non-sealed 子类意味着:该类型可被任意外部类继承,且这些新增子类不在原始 permits 名单中,编译器无法枚举、也无法在 switch 中强制覆盖。一旦某个直接子类被标为 non-sealed,整个密封体系对该分支就失去穷尽控制能力。
- 即使父类是
sealed,只要有一个non-sealed直接子类(如non-sealed class Polygon extends Shape),所有针对Shape的 switch 就必须加default,否则编译失败 - IDE 和编译器不会警告“你用了 non-sealed,小心穷尽性失效”,它只忠实地执行规则:有
non-sealed→ 类型不封闭 → switch 必须兜底 - 后续有人继承
Polygon写出StarPolygon,哪怕没改任何业务代码,switch (shape)仍能通过编译——但运行时才可能出问题
守住穷尽性:只在必要处开放,且隔离使用
若确实需要开放扩展点,应将其与核心穷尽分支解耦,避免污染主类型判断流。
智能模型自动切换 V5.0.2 - 多模态感知,自动识别图片/视频/音频/代码/文本任务,切换最优模型。支持图片理解(qwen3-vl-plus)、视频音频(qwen3.5-plus)、代码(glm-5)、Office文档(MiniMax-M2.5)、推理等场景。零感知切换,无需手动操作。
- 把
non-sealed子类定义在独立的、语义明确的继承路径上,例如:
—sealed abstract class PaymentResult permits Success, Failure, CustomResult
— 其中final class Success和final class Failure是标准结果
— 而non-sealed class CustomResult extends PaymentResult专用于插件场景,业务主流程 switch 只处理前两者 - 禁止在关键领域模型主干上使用
non-sealed,比如订单状态(Pending、Shipped、Delivered)必须全为final或继续sealed - 对已存在的
non-sealed子类,可在其内部重新启用密封控制,例如:non-sealed class ValidationError extends DomainError { }合理;
但更安全的做法是:sealed class ValidationError extends DomainError permits MissingFieldError, InvalidFormatError,再让具体错误类型为final
用编译器和工具提前拦截风险
靠人工记忆容易疏漏,应把校验嵌入开发流程。
- 在构建脚本中添加检查:扫描所有
sealed类的直接子类,若发现non-sealed出现在非白名单包(如plugin.*或ext.*)中,直接失败 - 用 SpotBugs 或自定义 Checkstyle 规则检测“
sealed类的子类未声明修饰符”或“non-sealed出现在核心 domain 包下” - 在 CI 阶段运行一个轻量级验证程序:反射读取所有
sealed类的permits列表,确认每个子类的修饰符,并报告是否含non-sealed—— 若有,要求 PR 提交者附 Javadoc 说明开放理由
Switch 使用时坚持“无 default 即穷尽”原则
这是最直接的防线:凡是你希望获得编译期穷尽保障的 switch,必须确保其操作对象的类型层级中,**所有直接子类均为 final 或 sealed(且其子树最终收敛)**。
- 写 switch 前先看父类声明:如果
permits里出现non-sealed类,就别指望无default通过编译 - IDE 提示 “unnecessary default” 是健康信号;提示 “switch does not cover all possible values” 却又加了
default,说明你其实已经放弃了穷尽性,需重新评估设计 - 对必须支持扩展的场景,改用策略模式 + 注册表,而非依赖 switch 分发——把运行时多态交给明确的插件注册机制,不强求编译期全覆盖

















