解读JDK 16版本特性

246 阅读9分钟

作者:老九—技术大黍

B站视频:听Java虚拟机作者聊JDK 16特性

社交:知乎

公众号:老九学堂(新人有惊喜)

特别声明:原创不易,未经授权不得转载或抄袭,如需转载可联系笔者授权

前言

JDK 16版本是根据Java社区组织提出的JSR(Java规范请求) 390实现的第16版Java SE平台。

JDK 16版本于2021年3月16日最终定版,并且可以用于工业开发使用。

如果觉得我们这篇文章讲得还不够专业,那么请看B站由Oracle公司的Java虚拟机开发人员Mikael Vidstedt 对JDK 16特性的讲解。

好了,言归正传,我们来介绍JDK 16版本新增的17功能。

由于本人是计科系毕业的程序员,所以以下翻译都是参考,请大家不要当成标准。如果不足之处,请大家指正和补充。

功能

Vector API (Incubator)-矢量API(生成器)

image-20210407134348566.png

提供生成器模块的初始化迭代动作,语法jdk.incubator.vetor,它表示一种矢量计算,而该计算在运行时是一种非常可行的编译操作,它的可能性是通过优化矢量硬件指令来实现的,主要体现为通过 CPU构架支持这种矢量运算,从而取得了超过同等量级的计算效率。

**解读:**凡是和硬件直接打交到的编程语言,目前只有汇编、C/C++这些语言实现。也就是说,我们的Java虚拟机是使用C/C++来写的,并且还可能调用了底层的汇编语言才达到这种调用CPU硬件的架构的效果。从另外一个角度来说,再一次证明了不管Java怎么update,它最终还是跑不过C/C++程序的。当然,那种差异性可能对于我们实际的应用来说,其实并不有什么影响。但是,对我们Java应用开发人员来说,在优化应用时就非常简单了--换JDK、换硬件--搞定!

Enable C++14 Language Features(兼容C++14版本特性)

image-20210407140521615.png

在JDK C++源代码中允许使用C++14版本的特性,并且C++14的特性在会HotSpot虚拟机代码中使用。

**解读:**这个已经说得非常清楚了,Java平台是使用C++来实现的,并且它还根据C++版本的更新进行了自己的源代码更新。比如,现在的C++版本已经是从C++ 98->C++ 11->C++ 14->C++ 17->C++ 20版本。关于C++版本参见:C++之父谈C++ 20标准 ,我们在这里不再累述了。

Migrate from Mercurial to Git(项目迁移到Git)

image-20210407141436813.png

把OpenJDK社区源代码仓库从Mercurial迁移到Git。

解读:这个不用解释了,大家都懂的。

Migrate to GitHub(项目迁移到GitHub)

image-20210407141850914.png

修正上一条规范,把OpenJDK社区的源代码仓库从Git上迁移到GitHub中,其结果是把OpenJDK整合成GitHub上的一个项目,它包括JDK 11版本及以后版本的发布特性和JDK发布更新说明。

解读:这个不用解释了,大家都懂的。只是说明歪果仁做事非常地严谨。

ZGC: Concurrent Thread-Stack Processing(ZGC使用并发线程栈)

image-20210407142347240.png

把Java的垃圾回收器的线程处理方式从原来的安全点级别升级为并发处理阶段来执行。

解读:关于Java 11版本引入的ZGC垃圾回收器,它的功能主要有四个:

  • 支持TB量级的堆。有人吹可能会满足Java应用所有需求,但是从目前来看,大数据应用时代,TB只是洒洒水啦,因为大数据是讲PB量级的。
  • 最大GC停顿时间不超10ms,这个比较牛批。
  • 奠定未来GC特性的基础。
  • 最糟糕的情况下吞吐量会降低15%。嘿嘿,毕竟算法永远都是不完美的,能用就好!

我们认为,JDK 16正向着PB量级的垃圾回功能努力,加油吧,JAVA!

Unix-Domain Socket Channels(使用Unix领域套结字通道)

image-20210407143333307.png

在java.nio.channel包中添加了对Unix领域套结字支持功能,即扩展了支持AF_UNIX领域的套结字通道和服务端通道继承机制。

解读:计算机网络有很多种,计算网络通讯协议也很多种,要完美的封装网络编程,这是Java平台必须努力做的事情,当然其结果就是Java程序员的网络编程是非常简单的。详细内容可以参见Java网络编程第3版 一文。

Alpine Linux Port(兼容Alpine Linux)

image-20210407151714028.png

JDK可以在Alpine Linux平台上支持,并且支持其它版本的Linux操作系统可以使用它们的核心C函数库,并且支持x64和AArch64的硬件架构操作系统。

**解读:**这说明,不是所有JDK都能完善兼容世界所有的操作系统的,所以,我们在实际开发中,在我们使用Java语言来开发时,那么选择应用架构时,那是必须认真考虑的事情。不能相信Java的口号:write once, run anywhere! 那是吹牛批的。

Elastic Metaspace(弹性位元空间)

image-20210407152339270.png

更加及时地回收没有使用的HotSpot的类位元(比如,命名空间)内存给操作系统,减少位元空间占用,简单化位元空间代码实现以减少维护成本。

解读:所有的Java类会在HotSpot虚拟机中记录和维护的,因此,这个维护动作必须产生资源占用、内存消耗,以及影响Java程序的运算速度。所以,为了提高Java应用程序的运算效率,那么JDK 16版本做了这个处理动作。

Windows/AArch64 Port(兼容Windows操作系统)

image-20210407152917485.png

这个不用翻译了,大家都懂的。

Foreign Linker API (Incubator)(外部链接API)

image-20210407153010693.png

引入一种提供静态类型、纯Java访问本地代码的API。该API与外部内存API一起使用,它的作用是降低绑定本地库的错误出现率。

解读:我们知道Java调用平台本地代码和本地库原来一直都是通过JNI技术来实现。但是,我们也知道,凡是学习Java的程序员,一般很少使用JNI编程,因为它一般要求与C/C++混合编程。也就是,如果该Java不具备C/C++编程能力,那么想玩好JNI编程简单就是痴人说梦。为了解决这个问题,因此,我们可以认为在JDK 16版本中提供了JNI的简化版本编程技术。

Warnings for Value-Based Classes(基于值类的警告)

image-20210407153809578.png

指定原始数据类型的包装类进行不建议警告提示。并且对包装类的实例进行实例化时进行警告提示。

解读:在Java中有两大数据类型:原始数据类型和引用类型。原始数据类型直接映射了C/C++的内置数据类型,其运算效率是很高的,而Java后来弄一个包装类,并且从Java 5开始还搞了什么装箱和拆箱之类东西,其结果直接导致运算成本增高,现在是拨乱反正的时候了。

Packaging Tool(打包工具)

image-20210407155034471.png

提供一jpackage打包工具,它可以具有直接打包包含所有应用的功能。

解读:Java应用程序打包一直都是一个大问题。我们来看一下Java打包历史:

  • jdk8及以前--使用java -jar XXXXX.jar 命令来打包
  • jdk9及以后的模块化--多了一个moudle-info.java打包配置文件,然后我们使用gradle的jlink命令打包
  • 到了JDK 14版本后可以使用jpackage -h 命令打包
  • JDK 16版本终于稳定下来,使用jpackage打包后,在各种平台可以双击后运行

Foreign-Memory Access API (Third Incubator)(外部内存访问API)

image-20210407155836427.png

使用该API可以非常安全的和高效的从外部访问Java堆内存。

解读:前面已经讲提到过了,它与 外部链接API配套使用后才达到效果。可以让我们第三方应用访问Java平台的堆内存,呵呵,这是不是有一点指针的感觉啊?像这种术语,对于不知道底层原理的Java程序员来说,简直就是折磨啊~

Pattern Matching for instanceof

image-20210407160227444.png

升级了instanceof运算符的模式匹配功能。模式匹配实现程序中的通用逻辑匹配处理,即从对象中抽取组件条件,以便更加安全和精准表达语义。

Records(记录集)

image-20210407160508077.png

升级记录集功能,它们是用传输不稳定数据的类。记录集又被看成名义元组。

解读:我们可以简单地认为它是就是用处理volatile数据库的集合。因为,大部分Java程序员实在不能理解为会有volatile数据类型,并且在什么时候处理这些数据。因此,我们可以认为JDK提供了记录集解决让人头痛的问题。

Strongly Encapsulate JDK Internals by Default(默认深度封装)

image-20210407160927805.png

DK所有内部元素被默认深度封装,除了一些关键的内部API之外。比如,sun.misc.Unsafe包。允许第三方开发人员选择不使用这种从JDK 9开始的默认的深度封装。

解读:任何时候都有两面性,如果封装太深,那么Java就变成了C#;而如果太浅的封装,又让Java就也C++了,这个真是让人头痛的问题。所以,凡事都要平衡!

Sealed Classes (Second Preview)

image-20210407161356898.png

升级密封类和接口功能,密封类和接口限制其它类或者接口,同时也允许第三方开发人员继承这密封类和实现这些接口。

解读:说白了,就是给第三开发人员提供编码时设计的灵活度,即抽象类不抽象,接口不用太接口。就看我们第三方设计人员的主观把握了。当然,我还是很喜欢这一点的,因为给第三方开发人员提供了自主思考和判断的功能,让我们Java程序员没有“码农”的感觉,还是有编码的乐趣的。因为,这种设定可以让很多写出逼格很高的代码来,满足Java程序员敲代码的基本需求啊。

总结

本人的解读,纯属个人认知和观点,不代表其他任何人。

各位看官把它当成一篇趣文来读就行了,不要太认真了。因为,认真你就输了。

祝大家看太开心,希望真的能够给大家带来启发和帮助。

最后

记得给大黍❤️关注+点赞+收藏+评论+转发❤️

作者:老九学堂—技术大黍

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。