关于 JDK15 的简单理解
一、为什么要了解 JDK15?
2020 年 9 月 15 日,Oracle 官方发布了 JDK15 版本,及时关注官方的更新动态,可以让我们在日常开发中更合理的选择更加优秀的工具方法,避免使用一些过时的或一些即将被删除类和方法,保障程序的健壮性、稳定性、可移植性。
二、JDK15 都为我们带来了哪些东西?
JEP 339: Edwards-Curve 数字签名算法(EdDSA)
JEP 360: 密封类(预览)
JEP 371: 隐藏类
JEP 372: 删除 Nashorn JavaScript 引擎
JEP 373: 重新实现旧版 DatagramSocket API
JEP 374: 禁用和弃用偏置锁定
JEP 375: instanceof 的模式匹配(第二预览)
JEP 377: ZGC:可扩展的低延迟垃圾收集器
JEP 378: 文字块
JEP 379: Shenandoah:低暂停时间的垃圾收集器
JEP 381: 删除 Solaris 和 SPARC 端口
JEP 383: 外部存储器访问 API(第二个孵化器)
JEP 384: Records(第二预览)
JEP 385: 弃用 RMI 激活以进行删除
JEP:JDK Enhancement Proposals ,JDK 特性的新增和修改建议。
三、具体说一说 JDK15 的特性。
1. JEP 339: Edwards-Curve 数字签名算法(EdDSA)
官方描述:
EdDSA 是一种现代的椭圆曲线签名方案,与 JDK 中的现有签名方案相比,具有多个优点。
在相同的安全强度下,开发比现有的 ECDSA 实现(使用本机 C 代码)更好的性能的 EdDSA 平台无关的实现。例如,在安全性〜126 位时使用 Curve25519 的 EdDSA 应该与在安全性〜128 位时使用曲线 secp256r1 的 ECDSA 一样快。
假设平台在恒定时间内执行 64 位整数加/乘,请确保时序与秘密无关。另外,该实现将不会基于秘密分支。这些属性对于防止侧通道攻击非常有用。
简而言之:
Edwards-Curve 数字签名算法(EdDSA)实现加密签名功能。且比现有的 JDK 中的签名安全性和性能更高。
2. JEP 360: 密封类(预览)
官方描述:
通过密封的类和接口增强 Java 编程语言。密封的类和接口限制可以扩展或实现它们的其他类或接口。通过将 sealed 修饰符应用于其声明来密封类。然后,在 anyextends 和 implements 子句之后,该 permits 子句指定允许扩展密封类的类。
简而言之:
限定接口的实现或子类,不是所有的类都能继承此类或实现此类。
注意:
sealed:隐含子类 permits : 许可证
non-sealed:隐含非受限子类
final:隐含无子类
每个允许的子类都只能使用修饰符 final ,sealed 和 non-sealed 中的一个,且三者互斥。
代码实现:
3. JEP 371: 隐藏类
官方描述:
隐藏类是其他类的字节码不能直接使用的类。隐藏类适用于在运行时生成类并通过反射间接使用它们的框架。隐藏类可以定义为访问控制嵌套的成员,并且可以独立于其他类进行卸载。
简而言之:
隐藏类的超类型是由类加载器创建的,但隐藏类本身的创建并不涉及任何类加载器。所以可以方便的进行卸载且不用考虑安全问题,并且可以减少程序的内存占用。
4. JEP 372: 删除 Nashorn JavaScript 引擎
官方描述:
随着 ECMAScript 语言构造以及 API 的快速适应和修改,我们发现 Nashorn 难以维护。官方决定删除 Nashorn JavaScript 脚本引擎和 API,以及该 jjs 工具。
两个 JDK 模块将被永久删除:
jdk.scripting.nashorn-包含 jdk.nashorn.api.scripting 和 jdk.nashorn.api.tree 软件包。
jdk.scripting.nashorn.shell-包含 jjs 工具。
5. JEP 373: 重新实现旧版 DatagramSocket API(套接字)
官方描述:
用更易于维护和调试的更简单,更现代的实现来替换 java.net.DatagramSocket 和 java.net.MulticastSocketAPI 的基础实现。新的实现将很容易适应虚拟线程的工作,当前正在 Project Loom 中进行探索。
改动原因:
java.net.DatagramSocket 和 java.net.MulticastSocketAPI 的代码库及其基础实现很旧且脆弱:
实现可以追溯到 JDK 1.0。它们是传统 Java 和 C 代码的混合,难以维护和调试。
的实现 MulticastSocket 尤其成问题,因为它可以追溯到 IPv6 仍处于开发阶段。许多基本的本机实现都尝试以难以维护的方式协调 IPv4 和 IPv6。
该实现还存在一些并发问题(例如,异步关闭),需要进行大修才能正确解决。
此外,在驻留而不是阻塞系统调用中底层内核线程的虚拟线程的情况下,当前实现不适合此目的。随着基于数据报的传输再次获得牵引力(例如 QUIC),需要更简单,更可维护的实现。
6.JEP 374: 禁用和弃用偏置锁定
官方描述:
在 JDK 15 之前,始终启用并提供偏置锁定。使用此 JEP,除非 -XX:+UseBiasedLocking 在命令行上设置,否则在启动 HotSpot 时将不再启用偏置锁定。
改动原因:
确定是否需要继续支持偏向锁定的传统同步优化,这是维护成本很高的方法。有偏见的锁定会带来争用时需要进行昂贵的撤销操作的代价。
7.JEP 375: instanceof 的模式匹配(第二预览)
官方描述:
通过为操作员提供模式匹配来增强 Java 编程语言 instanceof。模式匹配使程序中的通用逻辑(即从对象中有条件地提取组件)得以更简洁,更安全地表示。
简而言之:
可以使我们的代码更加简洁。
代码示例:
8. JEP 377: ZGC:可扩展的低延迟垃圾收集器(转正)
官方描述:
对 ZGC 的测试表明它是稳定的,并且在撰写本文时,我们已经有几个月没有收到针对 ZGC 的新错误了。借助 ZGC 如今拥有的稳定性,功能集和平台支持,是时候删除其实验状态并使其成为产品功能了。
今天,可以通过-XX:+UnlockExperimentalVMOptions -XX:+UseZGC 命令行选项启用 ZGC 。使 ZGC 成为产品(非实验性)功能意味着-XX:+UnlockExperimentalVMOptions 不再需要该选件。
该 JEP 不建议更改默认 GC,该默认 GC 仍为 G1。
简而言之:
ZGC 垃圾收集器在 JDK15 成为正式版,我们可以通过-XX:+UseZGC 命令行选项启用 ZGC,但是需要注意的是默认的垃圾收集器仍然是 G1。
9. JEP 378: 文字块(转正)
官方描述:
将文本块添加到 Java 语言。文本块是多行字符串文字,它避免了大多数转义序列的需要,以一种可预测的方式自动设置字符串的格式,并在需要时使开发人员可以控制格式。
解决了在 Java 中,在字符串文字中嵌入 HTML,XML,SQL 或 JSON 片段"..."通常需要先进行转义和串联的大量编辑,然后才能编译包含该片段的代码。该代码段通常难以阅读且难以维护的问题。
代码示例:
错误代码示例:
注意:
10. JEP 379: Shenandoah:低暂停时间的垃圾收集器(转正)
官方描述:
将 Shenandoah 垃圾收集器从实验功能更改为产品功能。
在 JDK 12 和更高版本中,通过-XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC 选项启用了 Shenandoah 。将 Shenandoah 成为产品功能意味着-XX:+UnlockExperimentalVMOptions 不再需要。
简而言之:
Shenandoah 垃圾收集器功能转正,可以通过-XX:+UseShenandoahGC 直接使用,Shenandoah 的暂停时间与堆大小无关。
11. JEP 381: 删除 Solaris 和 SPARC 端口
官方描述:
删除所有特定于 Solaris 操作系统的源代码。
删除所有特定于 SPARC 体系结构的源代码。
更新文档和源代码注释以用于将来的版本。
改动原因:
当前正在开发的许多项目和功能(例如 Valhalla,Loom 和 Panama)都需要对 CPU 体系结构和特定于操作系统的代码进行重大更改。放弃对 Solaris 和 SPARC 端口的支持将使 OpenJDK 社区中的贡献者能够加速新功能的开发,这些新功能将推动平台向前发展。
12.JEP 383: 外部存储器访问 API(第二个孵化器)
官方描述:
引入一个 API,以允许 Java 程序安全有效地访问 Java 堆之外的外部内存。
在 Java 14 作为孵化 API,在 JDK15 中第二次孵化。
以 jdk.incubator.foreign 相同的名称包形式提供了外部存储器访问 API ;它引入了三个主要抽象:MemorySegment,MemoryAddress 和 MemoryLayout。
13.JEP 384: Records(第二预览)
官方描述:
使用 records 增强 Java 编程语言,record 是充当不可变数据的透明载体的类。记录可以看作是名义元组。
设计一个表达简单值集合的面向对象的构造。
帮助程序员专注于对不可变数据进行建模,而不是对可扩展行为进行建模。
自动实现数据驱动的方法,例如 equals 和访问器。
保留长期的 Java 原则,例如标称类型和迁移兼容性
官方示例:
简而言之:
似于 lombok,主要目的是为了简化作用,不用再写构造方法、equals,hashCode,toString 等方法。
代码示例:
14.JEP 385: 弃用 RMI 激活以进行删除
官方描述:
弃用 RMI 激活 机制以便将来删除。RMI 激活是 RMI 的过时部分,自 Java 8 开始,RMI 激活是可选的。不会弃用 RMI 的其他部分。
改动原因:
分布式系统至少在过去十年中一直基于 Web 技术。Web 服务领域已经解决了有关穿越防火墙,筛选请求,身份验证和安全性的问题。延迟实例化资源由负载平衡器,业务流程和容器处理。这些机制在分布式系统的 RMI 激活模型中均不存在。
RMI 激活的使用量几乎消失了。没有证据表明有任何新的应用程序被编写为使用 RMI 激活,并且有证据表明很少有现有应用程序使用 RMI 激活。对各种开放源代码库的搜索几乎没有发现任何与激活相关的 API。
间而言之:
RMI 激活的功能使用极少,Web 服务有更优秀的问题解决方案,RMI 激活增加了维护的费用。
四、总结
总的来说,JDK15 新功能不多,可以根据自己的实际需要,根据 JDK 版本功能走向来选择合理的功能。
评论