JDK 16 新特性详解
· 阅读需 5 分钟
Java 16 作为一个非长期支持版本,带来了多项重要的语言特性和改进。
1. Records(正式发布)
Records 在 JDK 16 中正式发布,成为 Java 语言的标准特性:
public record Person(String name, int age) {
// 可以添加静态字段
public static final String UNKNOWN = "Unknown";
// 可以添加额外的构造器
public Person {
if (age < 0) {
throw new IllegalArgumentException("Age cannot be negative");
}
}
// 可以添加实例方法
public String getDescription() {
return name + " is " + age + " years old";
}
}
主要优点:
- 不可变数据类的简洁表示
- 自动生成 equals()、hashCode() 和 toString()
- 支持自定义构造器和方法
- 提高代码可维护性
2. 密封类(第二次预览)
密封类特性得到进一步改进:
// 密封接口
public sealed interface Vehicle
permits Car, Truck, Motorcycle {
void start();
}
// final 类实现
public final class Car implements Vehicle {
@Override
public void start() {
System.out.println("Car starting...");
}
}
// sealed 类实现
public sealed class Truck implements Vehicle
permits HeavyTruck, LightTruck {
@Override
public void start() {
System.out.println("Truck starting...");
}
}
// non-sealed 类实现
public non-sealed class Motorcycle implements Vehicle {
@Override
public void start() {
System.out.println("Motorcycle starting...");
}
}
3. instanceof 的模式匹配(正式发布)
模式匹配 instanceof 也正式发布:
// 新的模式匹配方式
public String getStringValue(Object obj) {
if (obj instanceof String s && !s.isEmpty()) {
return s.toUpperCase();
} else if (obj instanceof Number n) {
return String.format("%.2f", n.doubleValue());
}
return "Unknown";
}
4. Vector API(第一次孵化)
引入了新的 Vector API 用于 SIMD 操作:
// Vector 操作示例
void vectorComputation() {
var species = FloatVector.SPECIES_256;
var a = FloatVector.fromArray(species, arrayA, 0);
var b = FloatVector.fromArray(species, arrayB, 0);
var c = a.mul(b);
c.intoArray(arrayC, 0);
}
特点:
- 支持 SIMD(单指令多数据)操作
- 提供平台无关的向量计算
- 性能显著提升
5. 打包工具(正式发布)
jpackage 工具正式发布:
# 创建可执行文件
jpackage --name myapp --input target/ --main-jar myapp.jar
# 创建安装程序
jpackage --name myapp --input target/ --main-jar myapp.jar \
--type dmg --icon myapp.icns
功能:
- 创建原生安装包
- 支持多平台打包
- 可自定义安装选项
- 支持模块化应用
6. Unix-Domain Socket 通道
新增了对 Unix 域套接字的支持:
// 服务器端
var serverChannel = ServerSocketChannel.open(StandardProtocolFamily.UNIX);
serverChannel.bind(UnixDomainSocketAddress.of("/tmp/test.sock"));
// 客户端
var clientChannel = SocketChannel.open(StandardProtocolFamily.UNIX);
clientChannel.connect(UnixDomainSocketAddress.of("/tmp/test.sock"));
优势:
- 更高的性能
- 更好的安全性
- 同机器进程间通信的理想选择
7. 弹性元空间
引入了弹性元空间功能:
# 启用弹性元空间
java -XX:+UseG1GC -XX:+UseCompressedOops
改进:
- 更及时地将未使用内存返还给操作系统
- 减少内存占用
- 改进内存分配效率
8. 外部链接器 API(孵化)
提供了访问原生代码的新 API:
// 链接原生函数示例
public class NativeLinker {
public static void main(String[] args) {
Linker linker = Linker.nativeLinker();
MethodHandle strlen = linker.downcallHandle(
linker.lookup("strlen"),
MethodType.methodType(long.class, MemoryAddress.class)
);
}
}
9. 默认启用 ZGC
ZGC 现在默认启用:
# 不再需要显式启用
java -XX:+UseZGC # 可选
特点:
- 低延迟垃圾收集
- 可扩展到 TB 级堆
- 停顿时间不超过 1ms
10. 新增的警告
增加了新的废弃警告:
// 使用已废弃的 API 会产生警告
@Deprecated(since="16", forRemoval=true)
public class OldAPI {
// ...
}
总结
JDK 16 是一个重要的版本,它将多个预览特性转正,特别是 Records 和 instanceof 的模式匹配,这些特性大大提升了 Java 的开发效率和代码可读性。同时,通过引入 Vector API 和改进垃圾收集器,也在性能方面取得了显著进展。
虽然是非 LTS 版本,但 JDK 16 中的许多特性都非常实用。建议开发者积极尝试这些新特性,特别是已经正式发布的 Records 和模式匹配,它们可以帮助编写更简洁、更可维护的代码。对于仍在预览中的特性,建议在开发环境中进行评估和测试,为未来的正式使用做好准备。