Skip to content

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 release

Security 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 是一次"稳重型"更新:引入新特性,同时清理历史包袱。

基于 VitePress 构建