JDK 8 → JDK 17 代码适配与优化指南

“JDK 8 → JDK 17 代码适配与优化指南”,分成 必须改(不改可能编译或运行报错) 和 可优化(改了能用到新特性、提升代码质量) 两部分,并带上例子和注意事项。


一、必须改(不改会出问题)

1.移除的模块与类

  • Java EE & CORBA API(JDK 11 移除)
    例如:
    • javax.xml.bind(JAXB)
    • javax.activation
    • javax.annotation
    • javax.transaction(部分)
    • javax.jws、javax.xml.ws(JAX-WS)
  • 解决方法:
    • 改为使用 外部依赖(Maven/Gradle 添加 JAXB、JAX-WS 等)
    • 例如 JAXB:
<dependency>
  <groupId>jakarta.xml.bind</groupId>
  <artifactId>jakarta.xml.bind-api</artifactId>
  <version>3.0.1</version>
</dependency>

2.内部 API 访问受限(强封装)

  • 以前直接用 sun.misc.Unsafe 或 com.sun.* 可能会报错。
  • JDK 17 默认强封装,需要显式打开:
  • java --add-opens java.base/java.lang=ALL-UNNAMED \ --add-opens java.base/java.util=ALL-UNNAMED
  • 最佳做法:替换成官方 API,不要依赖内部类。

3.编译目标版本变化

  • JDK 9+ 编译参数变了:
    • 原来 javac -source 1.8 -target 1.8
    • 现在 javac --release 8
  • 如果你用 Maven:
<maven.compiler.release>8</maven.compiler.release>

4.JavaScript 引擎 Nashorn 被移除(JDK 15)

  • 如果项目中有:
  • ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
  • 会找不到。
  • 替代方案:
    • GraalVM JavaScript
    • 或外部 JS 引擎(Rhino 等)

5.默认 GC 变化

  • JDK 8 默认 Parallel GC
  • JDK 9+ 默认 G1 GC
  • 如果应用对延迟、吞吐敏感,要重新调 GC 参数:
  • # 原 Parallel GC -XX:+UseParallelGC # 或保留 G1 -XX:+UseG1GC

二、可优化(升级后可改进代码)

1.使用 var 类型推断(JDK 10)

var list = new ArrayList<String>(); // 推断为 ArrayList<String>

适合本地临时变量,不建议滥用(尤其是公开 API)。


2.集合工厂方法(JDK 9)

List<String> list = List.of("A", "B", "C");
Set<Integer> set = Set.of(1, 2, 3);
Map<String, String> map = Map.of("k1", "v1", "k2", "v2");

生成的集合是不可变的,避免无意修改。


3.改进的 switch 表达式(JDK 14 正式)

String result = switch (day) {
    case MONDAY, FRIDAY -> "Work";
    case SATURDAY, SUNDAY -> "Rest";
    default -> throw new IllegalStateException();
};

减少 break 漏写的风险。


4.instanceof 模式匹配(JDK 16)

if (obj instanceof String s) {
    System.out.println(s.toUpperCase());
}

不用再手动强转。


5.record 数据类(JDK 16 正式)

public record Point(int x, int y) {}

等同于:

public final class Point {
    private final int x;
    private final int y;
    public Point(int x, int y) { ... }
    public int x() { return x; }
    public int y() { return y; }
    // equals, hashCode, toString 自动生成
}

6.文本块(JDK 15 正式)

String json = """
    {
      "name": "ChatGPT",
      "type": "AI"
    }
    """;

多行字符串更直观。


7.Stream API 增强

  • JDK 8 → map, filter, collect
  • JDK 9 → takeWhile, dropWhile, iterate 重载
  • JDK 16 → Stream.toList()
  • var list = stream.filter(x -> x > 0).toList();

8.更强的 Random API(JDK 17)

RandomGenerator rng = RandomGeneratorFactory.of("Xoshiro256PlusPlus").create();
int num = rng.nextInt(100);

可选择多种算法。


三、升级建议步骤

  1. 先用 JDK 11 编译运行(LTS,兼容性好)
  2. 修掉被移除的 API
  3. 调整内部 API 访问
  4. 再升到 JDK 17
  5. 启用新特性优化代码
  6. 加 CI/CD 多版本测试
  7. 至少测试 --release 8 和 --release 17 编译
  8. 确保 jar 包向下兼容

从 JDK 8 到 JDK 17,升级只是开始,真正的价值在于落地应用。多实践、多调试,让代码在真实场景中经受考验,才会收获意料之外的成长。

原文链接:,转发请注明来源!