乐趣区

关于java:JDK16的新特性

简介

在 2021 年 3 月 16 日,JDK 的迎来了它的一个新版本 JDK16,尽管 JDK16 不是 LTS 版本,然而作为下一个 LTS 版本 JDK17 的后行版本,JDK16 为咱们带来了 17 个方面的晋升, 包含了新的语言个性、新的工具、内存治理的晋升等方面。

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

JDK16 的新个性

总的来说,JDK16 有上面的一些新个性:

  • 一些在 JDK14 中引入的新个性,最终在 JDK16 中确定了。
  • 内存治理的晋升
  • 新的打包工具
  • UNIX-Domain Socket channels
  • Value-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/

最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!

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

退出移动版