0

0

Java 17中的密封类(Sealed Classes)怎么用_继承关系的严格控制

P粉602998670

P粉602998670

发布时间:2026-03-14 11:43:03

|

702人浏览过

|

来源于php中文网

原创

密封类需显式列出允许继承的子类,子类必须与父类同模块并声明final/sealed/non-sealed,且仅当变量类型精确为密封类时才能支持switch穷尽检查。

java 17中的密封类(sealed classes)怎么用_继承关系的严格控制

密封类必须显式声明允许继承的子类

Java 17 的 sealed 类不是“默认封禁”,而是“白名单式放行”——你得亲手列出谁可以继承它,一个都不能少,也不能多。漏写、拼错类名、或子类不在同一模块(且未导出)都会直接编译失败。

常见错误现象:error: class X is not allowed to extend sealed class Y,往往是因为子类没在 permits 列表里,或者子类没用 final / sealed / non-sealed 明确表态。

  • permits 后面跟的是**类名**,不是包名或路径,比如 permits Dog, Cat,不能写成 permits com.example.Dog
  • 所有被允许的直接子类,必须和密封父类在同一个模块中;如果跨模块,需在 module-info.java 中用 opensexports 配合 requires 显式授权
  • 子类自己也得选好“身份”:用 final 封死继承链,用 sealed 继续限定下级,或用 non-sealed 主动开放(但此举会削弱密封性,慎用)

子类必须用 final/sealed/non-sealed 明确继承意图

密封体系下,每个直接子类都得向编译器“签收”自己的继承策略。不声明就报错,没有默认行为。这不是风格问题,是语法强制。

使用场景:比如定义一个 Shape 密封类,只允许 CircleRectTriangle 三种实现——其中 Circle 天然不可再扩展,就该用 finalRect 可能有 RoundedRect 等变体,那就用 sealed 并继续 permits;而 Triangle 若想留给外部库自由实现(极少见),才用 non-sealed

立即学习Java免费学习笔记(深入)”;

PatentPal专利申请写作
PatentPal专利申请写作

AI软件来为专利申请自动生成内容

下载
  • final 子类最安全,也是最常用的选择
  • sealed 子类必须也带 permits,形成可追溯的层级约束
  • non-sealed 会打破密封边界,JVM 不再保证穷尽性,switch 表达式无法启用 exhaustive 检查

配合 switch 表达式做穷尽检查时,类型必须是密封类本身

密封类真正的价值,在于让 switch 表达式能静态确认“已覆盖所有可能子类”。但这要求 switch 的操作数类型必须是密封类(如 Shape),而不是其父类(如 Object)或接口(如 Serializable)。

常见错误现象:写了完整 case 分支,却仍提示 switch expression does not cover all possible inputs——大概率是变量声明类型太宽泛,或用了泛型擦除后的原始类型。

  • 变量类型必须精确为密封类,例如 Shape s = ...;,而不是 Object sSerializable s
  • 泛型中若用到密封类,注意类型擦除影响:方法签名里写 void handle(Shape s) 才能触发穷尽检查,写成 <T extends Shape> void handle(T t) 就不行
  • IDE 和 javac 17+ 才支持该检查;低版本 JDK 编译会直接忽略 sealed 关键字

模块化环境下,permits 类必须可访问且未被封装

如果密封类在模块 A,子类在模块 B,光写 permits B.SubClass 不够——模块 A 必须导出包含该密封类的包,模块 B 必须对模块 A 有 requires,且子类所在包不能被模块 A 的 opensexports 排除。

性能影响几乎为零,但兼容性风险高:JDK 17 默认开启强封装,未显式配置的模块间类加载会失败,错误信息通常是 class XXX is in unnamed module, but module Y does not read it 或更隐晦的 NoClassDefFoundError

  • 模块 A 的 module-info.java 至少要写:exports com.example.shape;
  • 模块 B 的 module-info.java 要写:requires A;
  • 若子类含反射操作(如 getDeclaredMethods()),还需在模块 A 中加 opens com.example.shape to B;
密封类的约束力完全依赖编译期检查,运行时无额外开销,但也意味着——任何绕过 javac 的方式(比如字节码注入、动态代理、非模块化 classpath 拼接)都可能悄悄破坏你精心设计的继承边界。这点容易被忽略。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
switch语句用法
switch语句用法

switch语句用法:1、Switch语句只能用于整数类型,枚举类型和String类型,不能用于浮点数类型和布尔类型;2、每个case语句后面必须跟着一个break语句,以防止执行其他case的代码块,没有break语句,将会继续执行下一个case的代码块;3、可以在一个case语句中匹配多个值,使用逗号分隔;4、Switch语句中的default代码块是可选的等等。

569

2023.09.21

Java switch的用法
Java switch的用法

Java中的switch语句用于根据不同的条件执行不同的代码块。想了解更多switch的相关内容,可以阅读本专题下面的文章。

441

2024.03.13

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

492

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

382

2023.10.25

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

186

2023.11.23

java中void的含义
java中void的含义

本专题整合了Java中void的相关内容,阅读专题下面的文章了解更多详细内容。

134

2025.11.27

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1961

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

658

2025.10.17

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.4万人学习

C# 教程
C# 教程

共94课时 | 11.3万人学习

Java 教程
Java 教程

共578课时 | 82.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号