详解 Java 17 中新推出的密封类
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
类(非public类),可以控制只能被同一个包下的类继承
但很显然,这两种限制方式的粒度都非常粗,如果有更精细化的限制需求的话,是很难实现的。
新特性:密封类
为了进一步增强限制能力,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 {
}
整体结构有三层,具体如下图所示:
- 第一层: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新特性,阅读学习体验更佳!
欢迎关注我的公众号:程序猿DD。第一时间了解前沿行业消息、分享深度技术干货、获取优质学习资源
详解 Java 17 中新推出的密封类的更多相关文章
- 详解Java 8中Stream类型的“懒”加载
在进入正题之前,我们需要先引入Java 8中Stream类型的两个很重要的操作: 中间和终结操作(Intermediate and Terminal Operation) Stream类型有两种类型的 ...
- 详解Java中的clone方法
详解Java中的clone方法 参考:http://blog.csdn.net/zhangjg_blog/article/details/18369201/ 所谓的复制对象,首先要分配一个和源对象同样 ...
- 【转帖】windows命令行中java和javac、javap使用详解(java编译命令)
windows命令行中java和javac.javap使用详解(java编译命令) 更新时间:2014年03月23日 11:53:15 作者: 我要评论 http://www.jb51.ne ...
- 超全详解Java开发环境搭建
摘自:https://www.cnblogs.com/wangjiming/p/11278577.html 超全详解Java开发环境搭建 在项目产品开发中,开发环境搭建是软件开发的首要阶段,也是必 ...
- 详解Java GC的工作原理+Minor GC、FullGC
详解Java GC的工作原理+Minor GC.FullGC 引用地址:http://www.blogjava.net/ldwblog/archive/2013/07/24/401919.html J ...
- Protocol Buffer技术详解(Java实例)
Protocol Buffer技术详解(Java实例) 该篇Blog和上一篇(C++实例)基本相同,只是面向于我们团队中的Java工程师,毕竟我们项目的前端部分是基于Android开发的,而且我们研发 ...
- java基础(十五)----- Java 最全异常详解 ——Java高级开发必须懂的
本文将详解java中的异常和异常处理机制 异常简介 什么是异常? 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常. Java异常的分类和类结构图 1.Java中的所 ...
- 「跬步千里」详解 Java 内存模型与原子性、可见性、有序性
文题 "跬步千里" 主要是为了凸显这篇文章的基础性与重要性(狗头),并发编程这块的知识也确实主要围绕着 JMM 和三大性质来展开. 全文脉络如下: 1)为什么要学习并发编程? 2) ...
- 异常处理器详解 Java多线程异常处理机制 多线程中篇(四)
在Thread中有异常处理器相关的方法 在ThreadGroup中也有相关的异常处理方法 示例 未检查异常 对于未检查异常,将会直接宕掉,主线程则继续运行,程序会继续运行 在主线程中能不能捕获呢? 我 ...
随机推荐
- 什么是通用 SQL 函数?
1.CONCAT(A, B) – 连接两个字符串值以创建单个字符串输出.通常用于将两个 或多个字段合并为一个字段. 2.FORMAT(X, D)- 格式化数字 X 到 D 有效数字. 3.CURRDA ...
- java-web中的Filter&Listener
Filter过滤器 当访问服务器资源的时候,过滤器可以将i气你个球拦截下来,完成一些特殊的功能 过滤器的作用: 一般用于完成通用的操作,如验证登陆,统一的编码处理,敏感字符过滤.就是打游戏骂人,会出现 ...
- vsftd及虚拟用户
临时需要搭建一个ftp,突然忘记怎么搞了,重新整一下,以后备用 vsftd及虚拟用户 1.安装vsftpd yum install vsftpd 2.添加用户(用于虚拟用户映射) adduser se ...
- cpu设计过程
一款CPU是如何设计出来的? 前面一段,我们了解了芯片的制造过程,也就是如何从沙子中提取硅.把硅切成片,在片上通过离子注入实现PN结.实现各种二极管.三极管.CMOS管.从而实现千万门级大规模集成电路 ...
- 一次关于关系抽取(RE)综述调研的交流心得
本文来自于一次交流的的记录,{}内的为个人体会. 基本概念 实事知识:实体-关系-实体的三元组.比如, 知识图谱:大量实时知识组织在一起,可以构建成知识图谱. 关系抽取:由于文本中蕴含大量事实知识,需 ...
- SpringCloud微服务治理技术入门(SCN)
1.集群.分布式.微服务 首先先理解三个感念 什么是集群?: 同一个业务,部署在多个服务器上,目的是实现高可用,保证节点可用! 什么是分布式?: 一个业务分拆成多个子业务,部署在不同的服务器上,每个子 ...
- Spring Security的使用
spring security使用目的:验证,授权,攻击防护. 原理:创建大量的filter和interceptor来进行请求的验证和拦截,以此来达到安全的效果. Spring Security主要包 ...
- 搭建 SpringBoot 项目(前端页面 + 数据库 + 实现源码)
SpringBoot 项目整合源码 SpringBoot 项目整合 一.项目准备 1.1 快速创建 SpringBoot 项目 1.2 项目结构图如下 1.3 数据表结构图如下 1.4 运行结果 二. ...
- java集合(arraylist详解)
一.ArrayList概述 ArrayList是实现List接口的动态数组,所谓动态就是它的大小是可变的.实现了所有可选列表操作,并允许包括 null 在内的所有元素.除了实现 List 接口外,此类 ...
- 解决“WARNINGThe remote SSH server rejected X11 forwarding request.“警告
使用xshell连接服务器时,出现了"WARNING! The remote SSH server rejected X11 forwarding request.",意思是&qu ...