一帆磨砺

生活所迫,一叶孤舟

0%

Java版本特性-JDK16

引用参考文档链接

  1. jdk16特性列表
  2. JEP-Improve-Metaspace-Allocator
  3. 元空间(MetaSpace)一种新的内存空间诞生
  4. Java 16 中对于 Project Valhalla 的铺垫

写在开头

  1. record的开放使用对于一些简单的数据建模场景非常友好,能简化很多重复的编码工作
  2. instanceof正式放出,可以简化代码,提高代码可读性

矢量API

经历了一顿能干三顿饭的四年,已经不知道矢量计算的相关公示和理论了。有需求的可以看官方给出的案例简单了解下。

1
2
3
4
5
void scalarComputation(float[] a, float[] b, float[] c) {
for (int i = 0; i < a.length; i++) {
c[i] = (a[i] * a[i] + b[i] * b[i]) * -1.0f;
}
}

等效于

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static final VectorSpecies<Float> SPECIES = FloatVector.SPECIES_256;

void vectorComputation(float[] a, float[] b, float[] c) {

for (int i = 0; i < a.length; i += SPECIES.length()) {
var m = SPECIES.indexInRange(i, a.length);
// FloatVector va, vb, vc;
var va = FloatVector.fromArray(SPECIES, a, i, m);
var vb = FloatVector.fromArray(SPECIES, b, i, m);
var vc = va.mul(va).
add(vb.mul(vb)).
neg();
vc.intoArray(c, i, m);
}
}

可使用 C++14

Java有相当一部分代码底层实现是通过调用本地C++库实现,并且也支持开发人员自定义C++本地实现调用,本次版本是升级了C++的支持范围。

JDK 源码迁移至git

https://github.com/openjdk/

ZGC增强:并发线程堆栈处理

将 ZGC 线程堆栈处理从安全点移至并发阶段。减少ZGC在safepoint上的暂停时间,官方文档说是基本控制在1ms内。

Unix-Domain Socket Channels

对于本地、进程间通信,Unix 域套接字比 TCP/IP 环回连接更安全、更高效。

  • Unix 域套接字严格用于同一系统上的进程之间的通信。不打算接受远程连接的应用程序可以通过使用 Unix 域套接字来提高安全性。
  • Unix 域套接字进一步受到操作系统强制、基于文件系统的访问控制的保护。
  • 与 TCP/IP 环回连接相比,Unix 域套接字具有更快的设置时间和更高的数据吞吐量。
  • 对于需要在同一系统上的容器之间进行通信的容器环境,Unix 域套接字可能是比 TCP/IP 套接字更好的解决方案。这可以使用位于共享卷中的套接字来实现。
    Unix 域套接字长期以来一直是大多数 Unix 平台的一项功能,现在在 Windows 10 和 Windows Server 2019 中得到支持

兼容新系统:Alpine Linux

以及其他使用 musl 作为主要 C 库的 Linux 发行版,机器是x64和AArch64架构的

弹性元空间

更及时地将未使用的 HotSpot 类元数据(即元空间)内存返回给操作系统,减少元空间占用,并简化元空间代码以降低维护成本。
-XX:MetaspaceReclaimPolicy=(balanced|aggressive|none)

兼容Windows/AArch64

AArch64架构的兼容越来越多了,这次针对Windows的兼容应该是针对桌面软件领域。

开放新API调用本地代码

还在孵化阶段,目标应该是替换JNI,提供一种更高校更安全的调用本地方法的方式。

针对值类型的告警信息

可以先浏览Java 16 中对于 Project Valhalla 的铺垫,这篇文章对于值类型讲解和demo展示比较到位。

新的打包工具(正式开放使用)

JDK14开始孵化的打包工具,用以给各个系统打包各自平台的应用包:exe/pkg/dmg/deb/rpm

外部内存访问 API(第三次孵化)

  • MemorySegmentMemoryAddress之间的职责区别更清晰
  • 提供新的接口MemoryAccess,在简单的使用场景降低VarHandle API的使用需求,即简化普通场景的使用
  • 支持 shared segments(多线程场景)
  • 可以通过Cleaner注册segments(API 保证段的清理操作最多会被调用一次——要么显式地(通过客户端代码),要么隐式地(通过清理器)。)
    1
    2
    3
    4
    5
    MemorySegment segment = MemorySegment.allocateNative(100);
    Cleaner cleaner = Cleaner.create();
    segment.registerCleaner(cleaner);
    // do some work
    segment = null; // Cleaner might reclaim the segment memory now

instanceof增强开放使用

需要注意变量的声明,避免重复,重复不会影响使用,会影响代码可读性。

案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class Model {
public Model(String name) {
this.name = name;
}

private String name;

public String getName() {
return name;
}
}
public class Instanceof {

private static Model m = new Model("private");

public static void func(Object obj) {
if (obj instanceof String s) {
System.out.println(s);
} else if (obj instanceof Model m) {
System.out.println("instanceof:" + m.getName());
}
System.out.println("out:instanceof:" + m.getName());
}
}
public static void main(String[] args) {
Instanceof.func("sedg3");
Instanceof.func(new Model("demo"));
}

此时的输出结果为:

1
2
3
4
sedg3
out:instanceof:private
instanceof:demo
out:instanceof:private

record 开放使用

经过JDK14与JDK15的两次调整,在JDK16中开放使用,对于只需要数据建模的场景比较有用,需要额外注意record的限制规则:

  • 无法继承其他类,与Enum类似,父类限制为java.lang.Record
  • record修饰的类自动包含final规则限制
  • 类的内部属性默认都是final
  • record修饰的类不能在内部显示声明变量
    1
    2
    3
    4
        public record RecordPoint(int x, int y) {
    // Instance field is not allowed in record
    private final int z;
    }
  • 不能声明native方法

强封装JDK

建议开发人员通过标准API使用JDK内部类的内部元素,而不是直接使用。
提高JDK的安全性和可维护性。
影响的类涉足领域较多,如果迁移版本后编译失败,可以通过JEP-396查看替代方案

密封类(第二次预调整)

添加了non-sealed,当sealed类的子类使用non-sealed修饰时,该子类可以被其他类继承。

欢迎关注我的其它发布渠道