详解 Java 17中的新特性:“密封类”
作者:程序猿DD
博客:https://blog.didispace.com/
Java 17推出的新特性Sealed Classes经历了2个Preview版本(JDK 15中的JEP 360、JDK 16中的JEP 397),最终定稿于JDK 17中的JEP 409。Sealed Classes有两种主流翻译:密封类、封闭类。个人喜欢前者多一些,所以在本文中都称为密封类。其实Sealed Classes的其他许多语言中并不是什么新鲜事物,C#、Scala等高级语言中都有类似的名称,但意义和作用各不相同。下面就来一起认识一下Java 17中的Sealed Classes。
密封类的作用
在面向对象语言中,我们可以通过继承(extend)来实现类的能力复用、扩展与增强。但有的时候,有些能力我们不希望被继承了去做一些不可预知的扩展。所以,我们需要对继承关系有一些限制的控制手段。而密封类的作用就是限制类的继承。
已有的限制手段
对于继承能力的控制,Java很早就已经有一些了,主要是这两种方式:
final
修饰类,这样类就无法被继承了package-private
类,可以控制只能被同一个包下的类继承
但很显然,这两种限制方式的粒度都非常粗,如果有更精细化的限制需求的话,是很难实现的。
新手段:密封类
为了进一步增强限制能力,Java 17中的密封类增加了几个重要关键词:
sealed
:修饰类/接口,用来描述这个类/接口为密封类/接口non-sealed
:修饰类/接口,用来描述这个类/接口为非密封类/接口permits
:用在extends
和implements
之后,指定可以继承或实现的类
下面我们通过一个例子来理解这几个关键词的用法,更多Java新特性,欢迎关注Java前沿专栏,文档形式看Java新特性,阅读学习体验更佳,持续更新,收藏保存!
假设我们要设计一个游戏,这个游戏给用户选择的英雄种类分为三大类:
坦克
输出
辅助
每个种类下又有各种不同的具体英雄。所以,从我们传统的面向设计思路,会这样来创建:
// 英雄基类
public class Hero {}// 坦克英雄的抽象
public class TankHero extends Hero {}// 输出英雄的抽象
public class AttackHero extends Hero {}// 辅助英雄的抽象
public class SupportHero extends Hero {}// 坦克英雄:阿利斯塔
public class Alistar extends TankHero {}// 输出英雄:伊泽瑞尔
public class Ezreal extends AttackHero {}// 辅助英雄:索拉卡
public class Soraka extends SupportHero {}
整体结构有三层,具体如下图所示:如果您正在学习Spring Boot,那么推荐一个连载多年还在继续更新的免费教程:Spring Boot 2.x基础教程 | 程序猿DD
第一层:Hero是所有英雄的基类,定义英雄的基础属性
第二层:按英雄的分类的三个不同抽象,定义同类英雄的公共属性
第三层:具体英雄的定义
这个时候,为了避免开发人员在创建新英雄的时候,搞乱这样的三层结构。就可以通过引入密封类的特性来做限制。
假设我们希望第一、第二层是稳定的,对于第二层英雄种类的抽象不允许再增加,此时我们就可以这样写:
public sealed class Hero permits TankHero, AttackHero, SupportHero {}
通过sealed
关键词和permitspermits
关键来定义Hero是一个需要密封的类,并且它的子类只允许为TankHero
, AttackHero
, SupportHero
这三个。
完成这个改造之后,我们会发现TankHero
, AttackHero
, SupportHero
这三个类开始报错了,具体错误如下:
sealed, non-sealed or final modifiers expected
这是因为父类Hero被sealed
修饰之后,sealed
的密封要求被传递过来,此时子类就必须在sealed
、non-sealed
、final
之间选择一个定义,它们分别代表:
sealed
:继续延续密封类特性,可以继续指定继承的类,并传递密封定义给子类non-sealed
:声明这个类为非密封类,可以被任意继承final
:不允许继承
根据上面的假设需求,第一、第二层稳定,允许第三层具体英雄角色可以后期不断增加新英雄,所以三类抽象英雄的定义可以这样编写:
public non-sealed class TankHero extends Hero {}
而对于第三层的英雄角色,已经是最后的具体实现,则可以使用final定义来阻断后续的继承关系,比如这样:
public final class Ezreal extends AttackHero {}
通过这样的设置,这三层英雄的结构中第一第二层就得到了比较好的保护。
好了,今天的分享就到这里!关于Java新特性这个专题,我正在连载Java新特性专栏:https://www.didispace.com/java-features/,文档形式看Java新特性,阅读学习体验更佳!
我们创建了一个高质量的技术交流群,与优秀的人在一起,自己也会优秀起来,赶紧点击加群,享受一起成长的快乐。另外,如果你最近想跳槽的话,年前我花了2周时间收集了一波大厂面经,节后准备跳槽的可以点击这里领取!
推荐阅读
Java 17 新特性:密封类
Java 14 新特性:switch表达式增强
Java 17 新特性:switch的模式匹配(Preview)
详解 Java 17中的新特性:“密封类”相关推荐
- java - 详解 Java 17 中新推出的密封类
Java 17推出的新特性Sealed Classes经历了2个Preview版本(JDK 15中的JEP 360.JDK 16中的JEP 397),最终定稿于JDK 17中的JEP 409.Seal ...
- 详解 Java 17 中新推出的密封类
Java 17推出的新特性Sealed Classes经历了2个Preview版本(JDK 15中的JEP 360.JDK 16中的JEP 397),最终定稿于JDK 17中的JEP 409.Seal ...
- 详解Java 8十大新特性
前言: Java 8 已经发布很久了,很多报道表明Java 8 是一次重大的版本升级.在Java Code Geeks上已经有很多介绍Java 8新特性的文章,例如Playing with Java ...
- JDK 17:Java 17 中的新特性
始终严格的浮点语义.外部函数和内存 API 以及伪随机数生成器的统一 API 计划用于 9 月发布的 Java 长期支持版本. Java 17 的功能集现已冻结,标准 Java 的下一版本将拥有 10 ...
- atitit.jQuery Validate验证框架详解与ati Validate 设计新特性
atitit.jQuery Validate验证框架详解与ati Validate 设计新特性 1. AtiValidate的目标1 2. 默的认校验规则1 2.1. 使用方式 1.metadata用 ...
- python3.4和3.6的区别_详解Python3.6正式版新特性
按照Python官网上的计划,Python3.6正式版期望在2016-12-16号发布,也就是这周五.从去年的5月份开始,Python3.6版本就已经动手开发了,期间也断断续续的发布了4个Alpha版 ...
- Java 17 版本的新特性
Java 17 版本的新特性
- Java 17的这些新特性不看后悔
前言 2021年9月14日Java 17发布,作为新时代的农民工,有必要了解一下都有哪些新东西. Java 17是Java 11以来又一个LTS(长期支持)版本,Java 11 和Java 17之间发 ...
- Java 17的这些新特性,Java迈入新时代
前言 2021年9月14日Java 17发布,作为新时代的农民工,有必要了解一下都有哪些新东西. Java 17是Java 11以来又一个LTS(长期支持)版本,Java 11 和Java 17之间发 ...
最新文章
- SQL语法中drop,delete与truncate的区别
- 对偶问题(dual problem)
- Python 字符串大小写转换,值域范围
- OpenGL ES for Windows Mobile
- 为什么你学C++就那么难?
- 01_MyBatis EHCache集成及所需jar包,ehcache.xml配置文件参数配置及mapper中的参数配置
- 开源特训营 - Lesson 4 - 如何运营社区
- java高可用grpc_GRPC java 分布式调用链跟踪实践
- Linux debian设置主机不休眠教程
- 互联网晚报 | 11月25日 星期四 | 花呗启动品牌隔离;小米MIUI全球月活用户突破5亿;《长津湖》成中国影史票房冠军...
- 基于JAVA+SpringMVC+Mybatis+MYSQL的就业信息管理系统
- python sql查询返回记录_干货!Python与MySQL数据库的交互实战
- Python 连接开放航空交通数据,轻松构建航班跟踪应用!
- UVA11426 GCD - Extreme (II)【欧拉函数】
- 1.2Android系统移植的主要工作
- 黑群晖折腾记(二)-为不支持通信的UPS 增加断电自动关 NAS
- 台式电脑网络连接配置异常_专为电竞和内容创作者而生!体验惠普 ENVY TE01台式机...
- 3.Anaconda安装python环境
- Android模仿QQ的左右滑动切换界面和下拉更新的效果
- omv 网站服务器,折腾篇 篇一:小白也爱折腾 篇一:N1全小白装NAS(omv)
热门文章
- 打破平台限制,小程序如何在硬件设备上运行?
- 联发科wifi芯片模块处理器介绍
- 免费分享HTML5清新文艺个人博客文章类模板(支持移动设备)
- TensorFlow和Caffe、MXNet、Keras等其他深度学习框架的对比
- 林海雪原锻造“特战利刃”——直击第78集团军某特战旅冬训
- 封面你来定,给《新程序员·云原生和全面数字化时代》选封面啦
- 华为锁屏久了就显示无法连接服务器,ios 锁屏后网络连接服务器
- 虚拟机扩容,解决虚拟机磁盘根目录不足
- MinGW/GCC/CodeBlocks 等在 Win7 编译出现 Permission Denied 错误 - 解决方法
- 用于活动检测的上下文多尺度区域卷积三维网络