写点什么

JDK16 的新特性

作者:程序那些事
  • 2021 年 11 月 11 日
  • 本文字数:2925 字

    阅读完需:约 10 分钟

JDK16的新特性

简介在 2021 年 3 月 16 日,JDK 的迎来了它的一个新版本 JDK16,虽然 JDK16 不是 LTS 版本,但是作为下一个 LTS 版本 JDK17 的先行版本,JDK16 为我们带来了 17 个方面的提升,包括了新的语言特性、新的工具、内存管理的提升等方面。


所以一起来看看,JDK16 到底为我们提供了些什么新的特性。


JDK16 的新特性总的来说,JDK16 有下面的一些新特性:


一些在 JDK14 中引入的新特性,最终在 JDK16 中确定了。内存管理的提升新的打包工具 UNIX-Domain Socket channelsValue-based Classes 的警告 Encapsulating JDK Internals by default 提供了 C++ 14 语言特性其他的一些预览版本的新特性下面图是 JDK 从 8 开始到 16 的新特性个数:


可以看到 JDK8 和 JDK9 是最多的,后面基本上变动比较少。


JDK8 引入了 stream,lambda,泛型等一系列非常有用的特性。而 JDK9 则引入了新的 JPMS 模块化系统,所以变动比较多。


相对而言,JDK10 之后变动基本上比较小,也有可能跟固定 6 个月发一次版本有关系。毕竟时间比较短,所以版本的变动也比较小。


注意,JDK16 并不是一个 LTS 版本,在 9 月发布的 JDK17 才是!,大家可以关注我的后续关于 JDK17 新特性的文章。到现在为止,JAVA 的 LTS 版本就有 JDK8,JDK11 和 JDK17 了。你现在用的是哪个呢?


语言方面的提升 JDK16 在语言上的提升主要有两个:Pattern matching 和 records。这两个新特性都是在 JDK14 中作为预览版本引入了,最终到 JDK16 变成了 final 版本。


先来看一下 Pattern matching, Pattern matching 主要说的就是 instanceof 关键词,我们知道在 JAVA 中判断一个对象是不是某个类的实例,则可以使用 instanceof,如果是该类的实例或者子类,则返回 true,否则返回 false。


但是在判断完之后,要想使用对应的对象,还需要显示的进行类型转换如下所示:


//传统写法 if(site instanceof String){String stringSite = (String)site;System.out.println(stringSite.length());}在 JDK16 中的 Pattern matching 中,可以这样写:


//JDK16 写法 if(site instanceof String stringSite){System.out.println(stringSite.length());}另外一个 final 版本的就是在 JDK14 和 15 中引入的 Records,Records 是一个特殊的 java 类,主要用来表示不可变对象的结构体。


来看一个 Records 的定义:


public record Address(String addressName,String city) {}上面我们定义了一个 Address 对象,它有两个属性,分别是 addressName 和 city,如果反编译上面代码的编译结果,可以得到:


public record Address(String addressName, String city) {public Address(String addressName, String city) {this.addressName = addressName;this.city = city;}


public String addressName() {    return this.addressName;}
public String city() { return this.city;}
复制代码


}


实际上就等于传统的:


public class AddressOld {


private final String addressName;private final String city;
public AddressOld(String addressName, String city) { this.addressName = addressName; this.city = city;}
public String getAddressName() { return addressName;}
public String getCity() { return city;}
复制代码


}


但是在编写上要方便和简单很多。


内存管理方面的提升在看看内存管理方面的提升,主要有两方面:Elastic Metaspace 和 ZGC 的并发线程堆栈处理。


Metaspace 的主要功能是管理类的元数据的内存。 引入 Elastic Metaspace 是为了改进 HotSpot JVM 中元空间内存的分配和释放。 可以更快地将不需要的内存返回给操作系统,从而减少开销和内存碎片。


Elastic Metaspace 使用较小的块分配内存,并通过将未使用的元空间内存返回给操作系统来提高弹性。 它可以提高性能并降低维护成本。


那么什么是 ZGC 的并发线程堆栈处理呢?


我们知道 ZGC 是 HotSpot JVM 中一种低延时的垃圾回收算法。但是在线程的堆栈处理过程中,总有一个制约因素就是 safepoints。在 safepoints 这个点,java 的线程是要暂停执行的,从而限制了 GC 的效率。


而 ZGC 的并发线程堆栈处理可以保证 java 线程可以在 GC safepoints 的同时可以并发执行。


Unix-Domain Socket Channel 一般来说 Socket 通信是基于 TCP/IP 的,但是熟悉 unix 的朋友应该知道,在 unix 中一切都是以文件形式存在的,即便是在内部进程的通讯也是如此。


如果是同一个 host 上的进程进行通讯,使用 unix 本身的 inter-process communication (IPC)无疑是最快的方式,并且更加安全。


所以在 JDK16 中增加了对 Unix-Domain Socket Channel 的支持。


Warning For Value-based Classes 这个是什么意思呢? 我们知道 java 中对应的 primary 类型都有一个 Object 类型,比如 int 对应的是 Integer。


如果是用 Integer 的构造函数,则我们可以这样构造:


Integer integer= new Integer(100);但是在 JDK16 中,这种构造函数已经被废弃了:


@Deprecated(since="9", forRemoval = true)public Integer(int value) {    this.value = value;}
复制代码


我们可以直接这样写:


Integer integer2= 100;封装内部的 JDK 包一般来说,我们用的包都是 JDK 公开的 API,但是有时候还是会用到一些 JDK 内部使用的类,这种类是不建议直接在外部使用的,JDK16 对大部分的这种类做了封装,后面大家直接在标准 JDK 中查找使用即可。


C++ 14 语言特性这个是值 JDK 底层的 C++ 源代码使用 C++ 14 语言特性,一般的 JDK 使用者是无法直接感受的。


预览语言新特性在 JDK16 中还加入了几个预览的语言新特性.这里主要讲一下 Vector API 和 Sealed Classes.


Vector API 的想法是提供一种向量计算方法,最终能够比传统的标量计算方法(在支持 CPU 架构上)执行得更好。什么叫做向量计算呢?熟悉 pandas 的朋友可能知道,在 pandas 可以方便的对矩阵进行计算,如果用 java 实现则需要计算矩阵中的每个元素,非常麻烦,这也是 python 的 pandas 库能够流行的原因。


现在 JDK16 也可以做到了,我们一起来看看,先是传统写法:


//传统写法 int[] x = {1, 2, 3, 4};int[] y = {4, 3, 2, 1};


    int[] c = new int[x.length];
for (int i = 0; i < x.length; i++) { c[i] =x[i] * y[i]; }
复制代码


如果我们希望两个数组的数字相乘,则只能进行每个元素的遍历。现在的写法:


    var vectorA = IntVector.fromArray(IntVector.SPECIES_128, x, 0);    var vectorB = IntVector.fromArray(IntVector.SPECIES_128, y, 0);    var vectorC = vectorA.mul(vectorB);    vectorC.intoArray(c, 0);
复制代码


我们构建两个 Vector 变量,直接调用 Vector 类的 mul 方法即可。


fromArray 中有三个参数,第一个是向量的长度,第二是原数组,第三个是偏移量。因为一个 int 有 4 个字节,所以这里我们使用 SPECIES_128。


Sealed Classes 是在 JDK15 中引入的概念,它表示某个类允许哪些类来继承它:


public sealed class SealExample permits Seal1, Seal2{}


public non-sealed class Seal1 extends SealExample {}


public final class Seal2 extends SealExample {}final 表示 Seal2 不能再被继承了。non-sealed 表示可以允许任何类继承。


总结以上就是 JDK16 给我们带来的新特性,总体而言是很有用的,大家觉得呢?


本文例子 learn-java-base-9-to-20


本文已收录于 http://www.flydean.com/26-jdk16-new-features/


最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!


欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

发布于: 2021 年 11 月 11 日阅读数: 6
用户头像

关注公众号:程序那些事,更多精彩等着你! 2020.06.07 加入

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧,尽在公众号:程序那些事!

评论

发布
暂无评论
JDK16的新特性