if (obj instanceof String s) {
    // Let pattern matching do the work!
    // varialble s can be used here
    ...
}

如果obj的真实类型是String,则变量s可以在if语句中使用,但是如果obj的类型不是String,则s不能用在后续的变量命名中:

record Point(int x, int y) { }

如果对类的属性初始化的时候有定制逻辑,也是支持的

ZGC只有三个STW阶段:初始标记,再标记,初始转移。其中,初始标记和初始转移分别都只需要扫描所有GC Roots,其处理时间和GC Roots的数量成正比,一般情况耗时非常短;再标记阶段STW时间很短,最多1ms,超过1ms则再次进入并发标记阶段。即,ZGC几乎所有暂停都只依赖于GC Roots集合大小,停顿时间不会随着堆的大小或者活跃对象的大小而增加。与ZGC对比,G1的转移阶段完全STW的,且停顿时间随存活对象的大小增加而增加。

4. 可弹性伸缩的元数据区

JDK16对元数据区切分为更小的内存块,并将不再使用的内存快速返还给操作系统,对于频繁加载和卸载类的应用来说这一优化可以产生大量的空闲内存,提升整个JVM的性能

5. 支持Unix套接字

在2019 Windows Server和Windows 10提供了对Unix套接字的支持,Unix套接字常用于本地进程之间通信,相比于TCP协议,本地进程使用Unix套接字可以更高效安全的通信。JDK16新增了一个适配Unix套接字的新接口java.net.UnixDomainSocketAddress用于支持这一特性

6. 新的打包工具jpackage

支持将Java程序打包为对应平台的可执行程序

  • linux: deb和rpm
  • mac: pkg和dmg
  • Windows: msi和exe 假如我们在lib目录下有一个jar包组成的应用,并且main.jar包含main方法,则可以使用下面的语句产生对应平台的可执行程序
Double d = 20.0;
synchronized (d) { ... } // javac warning & HotSpot warning
Object o = d;
synchronized (o) { ... } // HotSpot warning

8. 对JDK内部方法提供强制的封装

这个更新目的是为了引导开发者放弃使用JDK内部类转为使标准的API接口,除了例如sun.misc.Unsafe这样内部关键的接口之外,其他所有内部元素都提供默认的封装。使用了JDK内部接口的代码再JDK16下编译会失败,JVM参数-–illegal-access能够控制这一行为,要知道从JDK9到JDK15,这个参数默认的值都是warning,而现在已经变成了deny

9. 提供向量计算的API

之前向量计算的API在JDK中是缺失的,常见的二方库有colt和commons-math3,这些二方库在版本老旧,在易用性上也比较差,此次JDK16引入的向量计算的API针对多数现代CPU使用的SIMD指令进行了优化,大幅提升了计算性能

10. 对原生代码的调用提供更方便的支持

相比于JNI,提供更方便的方法用于调用原生代码,比如我们想在Java代码中调用size_t strlen(const char *s);这个原生C函数,我们只需要这样写:

public abstract sealed class Shape 
    permits com.example.polar.Circle,
            com.example.quad.Rectangle,
            com.example.quad.simple.Square { ... }

比如在上面的这个例子中,类Shape只能限定被Circle,Rectangle和Square继承

JKD16正式发布,新特新一览_编程