这是我参与11月更文挑战的第11天,活动详情查看:2021最后一次更文挑战
欢迎关注公众号OpenCoder,来和我做朋友吧~❤😘😁🐱🐉👀
JDK 17 sealed classes密封类
1.简介
- 密封类(class)和接口(interface)限制哪些其他类或接口可以扩展(extends)或实现(implements)它们。
- 密封类JDK 15 中作为预览功能提供,并在JDK 16 中作为预览功能进行了改进。
- 现在在 JDK 17 中,密封类被最终确定,与 JDK 16 没有任何变化。
2.目标
- 允许类(class)或接口(interface)的作者控制负责实现它的代码。
- 提供比访问修饰符更具声明性的方式来限制超类的使用。
- 支持模式匹配(例如switch模式匹配中的案例)
3.动机
为什么要设计密封类(sealed classes)?
- 类和接口的继承层次结构
例如,作者想要提供关于常见、已知平面几何图形的一套API
* 图形Shape
+ 圆形Circle
- 正圆形Round
- 椭圆形Oval
+ 多边形Polygon
- 三角形Triangle
- 四边形Quadrilateral
+ 其他OtherShape
- 需求:期望超类(图形Shape)可以被访问、但是又不想被扩展(子类仅限于作者定义的已知的图形)
* Shape 也不能是包访问权限 应该是public:因为期望被开发者访问使用
* Shape 不能是final:否则作者自定的图形不能扩展
- 为了解决上述问题,引入sealed classes
1 | java复制代码public abstract sealed class Shape |
4.密封类语法
sealed class 父类 permits 子类1,子类2 ....
表示父类是密封类,指定可以被继承的有子类1,子类2 …
permits
指定的子类必须在父类的附近
- 在同一个模块中(module jdk9新增),(父类在一个命名的模块中)
- 或在同一包中(package),(父类在一个未命名的模块)
- 子类在大小和数量上都很小时,可以同父类定义在一个java文件中
permits
指定的子类必须直接继承该父类permits
指定的子类在定义时必须使用以下三种修饰符中的一种
- final:表示该子类是最终的,不能被继承
- sealed:表示该子类是密封类,可以被指定的其他类继承
- non-sealed:表示该子类是非密封类,可以被任意其他类继承
4.1子父类在同一模块中
- module-info.java
1 | java复制代码module sealed_class_demo { |
- 代码
1 | java复制代码public abstract sealed class SupperClass permits A, B, C { |
- 否则会编译错误
4.2子父类在同一个包中
- 代码
1 | java复制代码public abstract sealed class SupperClass permits A, B, C { |
4.3子父类定义在同一个java文件中
- 子类在大小和数量上都很小时,可以同父类定义在一个java文件中
- 代码
1 | java复制代码public abstract sealed class SupperClass { |
4.4子类修饰符
permits
指定的子类在定义时必须使用以下三种修饰符中的一种- 代码
1 | java复制代码// 密封类SupperClass 指定子类 A B C |
5.密封接口
sealed interface 接口 permits 实现类1,实现类2 ....
- 代码
1 | java复制代码public sealed interface Inter permits A,B,C{ |
6.JDK中的密封类
- ConstantDesc是JDK12 中出现的一组API。定义了一些JVM中已知的符号引用,常量池中的常量描述符
- JDK17 使用密封类对已知的继承体系做了优化
- 代码
1 | java复制代码public sealed interface ConstantDesc |
7.模式匹配的支持
- 代码
1 | java复制代码sealed interface S permits A, B, C {} |
欢迎关注公众号OpenCoder,来和我做朋友吧~❤😘😁🐱🐉👀
本文转载自: 掘金