JDK 17 其他特性
JDK 17 作为 LTS 版本,除了那些明星特性外,还有一些值得了解的改进——以及一些"告别"。
新增的随机数生成器
JDK 17 统一了随机数 API。
旧 API vs 新 API
java
import java.util.random.*;
// ❌ 旧方式:各种 Random
Random random = new Random();
SecureRandom secure = new SecureRandom();
ThreadLocalRandom threadLocal = ThreadLocalRandom.current();
// ✅ 新方式:统一接口
RandomGenerator generator = RandomGenerator.getDefault();
for (int i = 0; i < 5; i++) {
System.out.println(generator.nextInt(100)); // 0-99
}
// 获取特定类型的生成器
RandomGenerator strong = RandomGenerator.of("SecureRandom");命名生成器
java
// JDK 17+ 支持命名生成器
RandomGenerator l32x64 = RandomGenerator.of("L32X64MixRandom");
RandomGenerator xoshiro = RandomGenerator.of("Xoshiro256PlusPlus");Stream.toList()
JDK 16 引入的便利方法。
java
import java.util.List;
import java.util.stream.*;
// ❌ 旧方式
List<String> list1 = stream.filter(s -> s.length() > 3).collect(Collectors.toList());
// ✅ 新方式(JDK 16+)
List<String> list2 = stream.filter(s -> s.length() > 3).toList();toList() 返回的是不可变列表,而 collect(Collectors.toList()) 返回的是可变列表。
Objects.checkIndex()
JDK 9 引入的数组索引检查方法。
java
import java.util.Objects;
// 检查索引是否在 [0, length) 范围内
int index = Objects.checkIndex(5, 10); // ✅ OK,返回 5
// 超出范围抛异常
int bad = Objects.checkIndex(15, 10);
// throws IndexOutOfBoundsException移除的功能
移除 AOT 和 JIT 编译器
JDK 17 彻底移除了 jaotc。
bash
# JDK 16 及之前:可以用 jaotc 编译
jaotc --output lib.so MyApp.class
# JDK 17+:jaotc 不存在了
# 替代方案:GraalVM Native Image
native-image --jar MyApp.jar MyApp详见移除 AOT 编译器。
移除 Applet API
Applet 彻底成为历史。
java
// JDK 17+:Applet API 已被移除
// <applet> 标签在浏览器中也不再支持
// 如果你的代码中有 Applet 相关代码,需要迁移到 Java Web Start 或现代 Web 技术Security Manager 废弃
JDK 17 废弃了 Security Manager。
java
// JDK 17:使用 Security Manager 会收到警告
System.setSecurityManager(new SecurityManager());
// WARNING: The Security Manager is deprecated and will be removed
// in a future releaseSecurity Manager 的设计初衷是沙箱安全,但在现代 Java 应用中几乎没人用。
有趣的细节改进
NPE 错误信息更友好
java
// JDK 8-15
java.lang.NullPointerException
// ❌ 信息模糊,不知道哪个环节出问题
// JDK 15+:JVM 参数 -XX:+ShowCodeDetailsInExceptionMessages
java.lang.NullPointerException: Cannot invoke "String.length()" because the return value of "User.getName()" is null
// ✅ 清楚地指出:user.getName() 返回了 null默认 UTF-8 编码
java
// JDK 17+:文件读写默认使用 UTF-8
// 以前需要显式指定:
// new FileReader(file, StandardCharsets.UTF_8)
// 现在可以直接:
new FileReader(file); // 默认 UTF-8小结
| 类别 | 特性 |
|---|---|
| 新增 | 统一随机数 API、Stream.toList()、Objects.checkIndex() |
| 改进 | NPE 信息更详细、默认 UTF-8 编码 |
| 移除 | AOT/JIT 编译器、Applet API、Security Manager 废弃 |
| 预览转正式 | Text Blocks、Records |
JDK 17 是一次"稳重型"更新:引入新特性,同时清理历史包袱。
