Java 开发工具包(JDK) 21 是 Oracle 标准 Java 实现的最新长期支持 (LTS) 版本,现已推出生产版本。比较实用的我看就5个,字符串模板、有序集合、记录模式、switch的模式匹配、虚拟线程,其他一般也用不大到。
1. JEP 430:字符串模板
对现有Java字符串处理进行增强。包括两个模板处理器STR和FMT。简单示例:
STR模板处理器:
String firstName = "Bill";
String lastName = "Duck";
String fullName = STR."{firstName} {lastName}";
| "Bill Duck"
String sortName = STR."{lastName}, {firstName}";
| "Duck, Bill"
FMT模板处理器:
String table = FMT."""
Description Width Height Area
%-12s{zone[0].name} %7.2f{zone[0].width} %7.2f{zone[0].height} %7.2f{zone[0].area()}
%-12s{zone[1].name} %7.2f{zone[1].width} %7.2f{zone[1].height} %7.2f{zone[1].area()}
%-12s{zone[2].name} %7.2f{zone[2].width} %7.2f{zone[2].height} %7.2f{zone[2].area()}
{" ".repeat(28)} Total %7.2f{zone[0].area() + zone[1].area() + zone[2].area()}
""";
| """
| Description Width Height Area
| Alfa 17.80 31.40 558.92
| Bravo 9.60 12.40 119.04
| Charlie 7.10 11.23 79.73
| Total 757.69
| """
2.JEP 431:有序集合
提供了SequencedCollection、SequencedSet、SequencedMap。关系如下:
3.JEP 439:分代 ZGC
通过扩展 ZGC 来为新对象和旧对象维护不同的代,从而提高应用程序性能。年轻的对象往往会早逝;维护不同的代将允许 ZGC 更频繁地收集年轻对象。使用分代 ZGC 运行的应用程序具有以下优势:分配停顿的风险较低,所需的堆内存开销较低,并且垃圾收集 CPU 开销较低。与非分代 ZGC 相比,这些好处应该是可以实现的,而不会显着降低吞吐量。
4.JEP 440:记录模式
使用记录模式增强 Java 编程语言以解构记录值。记录模式和类型模式可以嵌套,以实现强大的、声明性的、可组合形式的数据导航和处理。
示例:
// Java 16
record Point(int x, int y) {}
static void printSum(Object obj) {
if (obj instanceof Point p) {
int x = p.x();
int y = p.y();
System.out.println(x+y);
}
}
// Java 21
static void printSum(Object obj) {
if (obj instanceof Point(int x, int y)) {
System.out.println(x+y);
}
}
5.JEP 441:switch的模式匹配
switch 通过表达式和语句的模式匹配增强 Java 编程语言。扩展模式匹配switch允许针对多个模式测试表达式,每个模式都有一个特定的操作,以便可以简洁、安全地表达复杂的面向数据的查询。
示例:
static String formatterPatternSwitch(Object obj) {
return switch (obj) {
case Integer i -> String.format("int %d", i);
case Long l -> String.format("long %d", l);
case Double d -> String.format("double %f", d);
case String s -> String.format("String %s", s);
default -> obj.toString();
};
}
static void testFooBarNew(String s) {
switch (s) {
case null -> System.out.println("Oops");
case "Foo", "Bar" -> System.out.println("Great");
default -> System.out.println("Ok");
}
}
6.JEP 442:外部函数和内存 API
通过高效地调用外部函数并安全地访问外部内存,该 API 使 Java 程序能够调用本机库并处理本机数据,而没有 JNI(Java 本机接口)的脆弱性和危险性。该 API 之前已在JDK 20 和JDK 19中预览。JDK 21 预览版中的改进包括增强的布局路径,其中包含用于取消引用地址布局的新元素。
7.JEP 443:未命名模式和变量
使用未命名模式和未命名变量(可以初始化但不能使用)增强 Java 语言,未命名模式匹配记录组件而不说明组件的名称或类型。两者都由下划线字符 表示_。
未命名模式示例:
a instanceof Point(_, int y)
未命名的模式变量:
r instanceof Point _
r instanceof ColoredPoint(Point(int x, int _), Color _)
8.JEP 444:虚拟线程
虚拟线程是轻量级线程,可以显著减少编写、维护和观察高吞吐量并发应用程序的工作量。
创建虚拟线程示例:
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 10_000).forEach(i -> {
executor.submit(() -> {
Thread.sleep(Duration.ofSeconds(1));
return i;
});
});
}
9.JEP 445:未命名类和实例Main方法
核心目的是帮助教学和学习。
以后写 main 方法就变得简单了,不需要一堆的修饰符。如下:
class HelloWorld {
void main() {
System.out.println("Hello, World!");
}
}
甚至可以不需要类声明,代码削减:
void main() {
System.out.println("Hello, World!");
}
说明:未命名包中的类不能被命名包中的类显式引用。
10.JEP 446:作用域值
将支持在线程内和线程间共享不可变数据。它们优于线程局部变量,特别是在使用大量虚拟线程时。线程局部变量具有设计缺陷,包括无约束的可变性、无限制的生命周期和昂贵的继承。作用域值允许在大型程序中的组件之间安全地共享数据,而无需求助于方法参数。
11.JEP 448:向量API
引入 API 来表达向量计算,在运行时可靠地编译为支持的 CPU 架构上的最佳向量指令,从而实现优于同等标量计算的性能。
12.JEP 449:弃用 Windows 32 位 x86 端口
目标是在未来版本中删除该端口,原因是最后一个支持 32 位操作的 Windows 操作系统 Windows 10 将于 2025 年 10 月结束生命周期。
13.JEP 451:准备禁止动态加载代理
在 JDK 21 中,计划要求动态加载代理必须得到应用程序所有者的批准,就像代理启动时加载所要求的那样。此更改将使 Java 平台更接近默认完整性。
14.JEP 452:密钥封装机制 API
该提案的目标之一是使应用程序能够使用 KEM 算法,例如 RSA 密钥封装机制 (RSA-KEM)、椭圆曲线集成加密方案 (ECIES) 以及美国国家标准与技术研究院 (NIST) 的候选算法后量子密码学标准化过程。另一个目标是允许在传输层安全 (TLS) 等更高级别协议和混合公钥加密 (HPKE) 等加密方案中使用 KEM。安全提供商将能够以 Java 代码或本机代码实现 KEM 算法,并包括RFC 9180中定义的 Diffie-Hellman KEM (DHKEM) 的实现。
15.JEP 453:结构化并发
通过结构化并发 API 简化了并发编程,将在不同线程中运行的相关任务组视为单个工作单元。这简化了错误处理和取消,提高了可靠性并增强了可观察性。结构化并发之前在JDK 20和JDK 19中孵化,分别于 2022 年 3 月和 2022 年 9 月发布;它将作为java.util.concurrent包中的预览 API。这次唯一显著的变化是该StructuredTaskScope::Fork(…)方法返回 Subtask而不是 Future。结构化并发的目标包括推广一种并发编程风格,可以消除因取消和关闭而产生的常见风险,例如线程泄漏和取消延迟,以及提高并发代码的可观察性。