JDK 17
JDK 17 是继 JDK 11 之后的 LTS 版本。对业务开发最重要的是 Sealed Classes 正式发布;对旧系统迁移影响最大的是 JDK 内部 API 强封装。
Sealed Classes(正式)
java
public sealed interface PaymentResult
permits Paid, Rejected, Pending {}
public record Paid(String transactionId) implements PaymentResult {}
public record Rejected(String reason) implements PaymentResult {}
public non-sealed class Pending implements PaymentResult {}Sealed Class 与 Record 配合,可以明确领域状态的有限集合。JDK 17 的 switch 模式匹配仍是 Preview,因此不能把针对密封层次的模式 switch 当成正式语法。
Pattern Matching for switch(Preview)
java
static String format(Object value) {
return switch (value) {
case null -> "null";
case Integer number -> "int: " + number;
case String text -> "string: " + text;
default -> value.toString();
};
}该特性在 JDK 17 仅为第一轮 Preview,后续版本继续调整,直到 JDK 21 才正式发布。
增强的伪随机数生成器
java.util.random 引入统一的随机数生成器接口和可发现的算法实现。
java
RandomGenerator generator = RandomGenerator.of("L64X128MixRandom");
int value = generator.nextInt(100);普通 PRNG 不适用于密码学密钥、Token 等安全场景,安全随机数仍应使用 SecureRandom。
强封装 JDK 内部 API
JDK 17 不再支持通过 --illegal-access 一键放宽 JDK 8 时代内部包的反射访问。必要时只能针对具体包使用 --add-opens 或 --add-exports,并尽快替换内部 API。
bash
java --add-opens java.base/java.lang=ALL-UNNAMED -jar legacy-app.jar这类参数是兼容性逃生口,不应成为长期架构依赖。
安全与序列化
| 特性 | 说明 |
|---|---|
| Context-Specific Deserialization Filters | 可以按调用上下文选择反序列化过滤器 |
| Security Manager | 标记为待移除,不应再作为新系统沙箱方案 |
| Applet API | 标记为待移除 |
Java 原生反序列化属于高风险边界,应使用白名单过滤、限制对象图规模,并优先选择显式数据格式。
JVM 与平台
- 恢复始终严格的浮点语义,
strictfp不再产生实际差异。 - 增加 macOS/AArch64 端口,支持 Apple Silicon。
- macOS 使用新的 Metal 渲染管线。
- Foreign Function & Memory API 进入 Incubator。
- Vector API 进入第二轮 Incubator。
移除项
- 移除 RMI Activation。
- 移除实验性的 AOT 与 Graal JIT 编译器;这不等于删除 JVMCI,也不等于 GraalVM 不再存在。
JDK 8 → 17 升级检查表
- [ ] 构建工具、Spring、ORM、测试框架、字节码工具支持 JDK 17
- [ ] 不再依赖
sun.*、com.sun.*和非法深度反射 - [ ] JAXB/JAX-WS 等 Java EE API 已改为独立依赖
- [ ] CMS 和旧 GC 参数已替换,GC 日志改为
-Xlog:gc* - [ ] 容器 CPU、内存、堆比例和线程池已经压测
- [ ] TLS、证书、字符集、时区和序列化兼容性已经回归
- [ ] Preview/Incubator API 未进入要求长期兼容的生产接口
- [ ] 使用真实流量模型完成性能、延迟和内存基线对比