Java21 新特性
Java 21 是继 Java 17 之后的又一个长期支持(LTS)版本,于 2023 年 9 月 19 日发布,相较于 Java 17 引入了许多新特性和改进,涵盖语言特性、性能优化、并发模型、API 增强等方面。以下是对 Java 21 相比 Java 17 的主要新特性的详细总结,重点突出其提升,并尽量简洁:
1. 语言特性改进
- 虚拟线程(Virtual Threads,JEP 444,Java 21 正式化)
项目 Loom 的核心成果,引入轻量级线程,极大降低并发编程的开销,适合高吞吐量应用(如 Web 服务)。
与 Java 17 的平台线程相比,虚拟线程无需直接绑定到 OS 线程,创建和管理成本低,可支持百万级并发。
示例:
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { IntStream.range(0, 10000).forEach(i -> executor.submit(() -> { Thread.sleep(1000); System.out.println(i); })); }
Java 17 无虚拟线程,依赖传统线程模型,效率较低。
- 结构化并发(Structured Concurrency,JEP 453,Java 21 预览)
提供一种更简单的并发编程模型,将相关任务视为一个工作单元,简化错误处理和任务取消。
示例:
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) { Future<String> task1 = scope.fork(() -> "Result 1"); Future<String> task2 = scope.fork(() -> "Result 2"); scope.join().throwIfFailed(); System.out.println(task1.resultNow() + ", " + task2.resultNow()); }
Java 17 无此功能,需手动管理线程池和错误处理。
- 记录模式(Record Patterns,JEP 440,Java 21 正式化)
扩展模式匹配,允许解构记录类实例,简化复杂数据处理。
示例:
record Point(int x, int y) {} if (obj instanceof Point(int x, int y)) { System.out.println("Point at: " + x + ", " + y); }
Java 17 的记录类仅支持基本定义,模式匹配功能较弱。
- Switch 模式匹配(Pattern Matching for Switch,JEP 441,Java 21 正式化)
增强 switch 语句,支持类型模式和守卫条件,代码更简洁安全。
示例:
String result = switch (obj) { case Integer i when i > 10 -> "Large Integer: " + i; case Integer i -> "Small Integer: " + i; case String s -> "String: " + s; default -> "Unknown"; };
Java 17 的 switch 模式匹配为预览功能,Java 21 正式化并新增守卫模式支持。
- 字符串模板(String Templates,JEP 430,Java 21 预览)
简化字符串插值,支持嵌入表达式,减少拼接错误。
示例:
String name = "Alice"; String message = STR."Hello, \{name}!";
Java 17 依赖传统的字符串拼接或 String.format,易出错且繁琐。
- 未命名模式和变量(Unnamed Patterns and Variables,JEP 443,Java 21 预览)
允许在模式匹配中使用 _ 表示未使用的变量或模式,提高代码简洁性。
示例:
if (obj instanceof Point(_, int y)) { System.out.println("Y coordinate: " + y); }
Java 17 无此功能,需显式声明所有变量。
2. API 和标准库增强
- 序列集合(Sequenced Collections,JEP 431,Java 21)
引入 SequencedCollection 接口,支持有序集合操作(如获取首尾元素、反向遍历)。
示例:
SequencedCollection<String> seq = new ArrayList<>(); seq.addFirst("First"); seq.addLast("Last"); System.out.println(seq.getFirst()); *// First*
Java 17 无此统一接口,需依赖具体集合类实现类似功能。
- 外部函数和内存 API(Foreign Function & Memory API,JEP 442,Java 21 正式化)
提供高效的本地代码交互方式,取代 JNI,性能更高且更安全。
示例:
try (var arena = Arena.ofConfined()) { var segment = arena.allocate(100); *// 访问外部内存*}
Java 17 仅提供预览版,Java 21 正式化并优化。
- 向量 API(Vector API,JEP 448,Java 21 第六次孵化)
- 继续优化,支持高效向量计算(如机器学习任务),但仍为孵化状态。
- Java 17 提供早期孵化版,Java 21 进一步增强性能。
3. 性能和 JVM 优化
- 分代 ZGC(Generational ZGC,JEP 439,Java 21)
- ZGC 升级为分代垃圾收集器,将堆分为年轻代和老年代,减少扫描频率,提高性能。
- Java 17 的 ZGC 为非分代,暂停时间虽低,但在某些场景下效率不如 Java 21。
- 键封装机制 API(Key Encapsulation Mechanism API,JEP 452,Java 21)
- 提供标准化的加密密钥封装机制,增强安全性。
- Java 17 无此 API,需依赖第三方库实现类似功能。
- 性能改进:
- Java 21 优化了 JIT 编译、垃圾回收算法和运行时性能,尤其在云原生和微服务场景下表现更优。
- Java 17 的性能优化较为保守,Java 21 在内存管理和并发性能上更进一步。
4. 弃用和移除
- 移除过时 API:
- Java 21 移除了一些 Java 17 中标记为弃用的功能,如 ObjectOutputStream.PutField 和 Runtime.runFinalization(),推荐使用现代替代方案(如 try-with-resources)。
- 动态加载代理(Agent)现发出警告,未来可能默认禁用(JEP 451)。
- 安全管理器完全移除(JEP 411,Java 17 标记弃用,Java 21 移除):
- Java 21 不再支持安全管理器,推荐使用现代安全机制。
- Java 17 仍支持但已标记为废弃。
5. 迁移和兼容性
- 向后兼容性:
- Java 21 保持了较高的向后兼容性,迁移自 Java 17 通常较为平滑,但需注意移除的 API 和库兼容性。
- 挑战:
- 某些依赖反射或内部 API 的库可能需要更新。
- 动态代理加载的警告可能影响某些工具(如 Mockito)。
6. 其他改进
- Java Flight Recorder(JFR)增强:
- Java 21 改进了 JFR,新增了更多事件(如加密操作),便于性能监控。
- Java 17 的 JFR 功能较基础。
- Unicode 支持:
- Java 21 增强了 Character 类对新 Unicode 标准的支持(如表情符号处理)。
总结
Java 21 相较 Java 17 的最大亮点是 虚拟线程 和 结构化并发,显著提升了并发性能,适合现代高并发应用;记录模式 和 Switch 模式匹配 进一步简化代码;序列集合 和 外部函数和内存 API 增强了标准库和本地交互能力;分代 ZGC 和其他性能优化使 Java 21 在云原生和微服务场景下更高效。Java 21 作为 LTS 版本(支持至 2028 年或更久),是 Java 17 的理想升级目标,尤其适合需要现代化特性和长期支持的项目。