字数:约2500字 | 阅读时间:7分钟


作为一名Java开发者,你大概率遇到过这个问题:项目该用哪个JDK版本?

JDK 8虽然老了但到处都在用,JDK 17是LTS版本但线上还不多,JDK 21又有虚拟线程这种新东西,JDK 24刚刚发布——选择太多反而不知道选什么。

这篇文章不纠结于技术细节,直接从企业实战角度给你一个明确的答案。

先搞清楚一件事:LTS和非LTS

Oracle从JDK 17开始采用新的发布节奏:每6个月一个版本,每2年一个LTS(长期支持)版本。

非LTS版本只维护6个月,过了就不管了。LTS版本至少维护8年。

所以对企业开发来说,只看LTS版本就够了。

目前主流的LTS版本:

版本 发布时间 免费维护截止 核心特性
JDK 8 2014年 2030年底 Lambda、Stream、Optional
JDK 11 2018年 2026年底 模块化、HTTP Client、var
JDK 17 2021年 2029年底 Records、密封类、模式匹配预览
JDK 21 2023年 2031年底 虚拟线程、顺序集合、记录模式
JDK 25 2025年9月 2033年底 值类型(Valhalla)预览

注意:JDK 11的免费维护将在2026年底结束。如果你还在用JDK 11,今年就该规划升级了。

各版本选择建议

新项目:直接用JDK 21

没有历史包袱的新项目,JDK 21是最好的选择

理由很充分:

1. 虚拟线程是革命性的。

传统Java线程模型下,一个请求占一个线程,线程数量受限于系统资源。高并发场景下,你不得不依赖线程池、异步编程(CompletableFuture、WebFlux)来提升吞吐量。

虚拟线程彻底改变了这个局面。它由JVM调度,创建成本极低,你可以轻松创建上百万个虚拟线程。从此告别复杂的异步编程模型——用同步的方式写代码,享受异步的性能。

1
2
3
4
5
6
7
8
9
10
// 虚拟线程的使用极其简单
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 10_000).forEach(i -> {
executor.submit(() -> {
// 每个任务一个虚拟线程,没有线程池大小限制
callRemoteService(i);
return null;
});
});
}

2. 语法现代且成熟。

JDK 17引入的Records、密封类、switch表达式,在JDK 21中已经完全稳定。代码更简洁、更安全:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Record:一行定义不可变数据类
public record Point(int x, int y) {}

// 密封类:限定继承范围
public sealed interface Shape permits Circle, Rectangle {}
public record Circle(double radius) implements Shape {}
public record Rectangle(double width, double height) implements Shape {}

// switch表达式 + 模式匹配
String describe(Shape shape) {
return switch (shape) {
case Circle(var r) -> "圆,半径" + r;
case Rectangle(var w, var h) -> "矩形," + w + "x" + h;
};
}

3. 生态支持到位。

Spring Boot 3.2+、Tomcat 10.1+、各种主流框架都已完成JDK 21适配。不会再遇到兼容性问题。

老项目(JDK 8):尽快规划升级到17或21

JDK 8虽然维护到2030年,但它确实老了。很多新库和框架已经不再支持JDK 8。

升级路径建议:JDK 8 → JDK 17 → JDK 21。

不要一步跳到21。先升到17验证兼容性,再升到21。中间可以借助这些工具:

  • jdeps:分析项目的模块依赖
  • jdeprscan:扫描已废弃的API使用
  • Maven Compiler Plugin:切换目标版本
  • Spring Boot Migrator:Spring项目的自动升级工具

JDK 11项目:今年必须升级

前面说了,JDK 11的免费维护在2026年底结束。从JDK 11升到JDK 21的迁移成本比你想的小得多。

JDK 11到17的Breaking Changes主要集中在:

  • 移除了javax包的部分内部API(如sun.misc.Unsafe的部分方法)
  • Nashorn JavaScript引擎被移除
  • CMS垃圾回收器被移除

如果你的代码没有直接使用这些特性,基本是无感升级。

选择哪个发行版?

OpenJDK有多个发行版,选择起来也不少纠结:

发行版 维护方 特点
Eclipse Temurin Eclipse基金会 社区首选,完全免费,TCK认证
Amazon Corretto AWS 长期免费,AWS优化,生产推荐
Azul Zulu Azul 多平台支持,性能优化好
Oracle JDK Oracle 个人免费,商用付费(2024年后)
Dragonwell 阿里 面向国内电商场景优化
Kona 腾讯 面向腾讯云场景优化

企业开发推荐:Eclipse Temurin 或 Amazon Corretto。

两者都是完全免费、TCK认证、社区活跃。选哪个看你的云平台偏好——AWS用户用Corretto,其他用Temurin。

国内场景如果追求极致性能,可以考虑Dragonwell或Kona,但要注意版本更新可能滞后于社区版。

一个容易被忽略的问题:JDK版本一致性

我见过不少线上事故,根因都是开发和生产的JDK版本不一致

比如开发环境用JDK 21,生产环境用JDK 8。本地跑得好好的,一上线就报ClassNotFoundException。排查半天才发现是某个类在JDK 8的rt.jar里不存在。

建议:

  • 使用Docker统一JDK版本
  • CI/CD流水线中指定JDK版本
  • .java-version.tool-versions文件管理本地版本
  • Maven Compiler Plugin锁定sourcetarget版本
1
2
3
4
5
6
7
8
9
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.12.1</version>
<configuration>
<source>21</source>
<target>21</target>
</configuration>
</plugin>

2026年的版本选择总结

一句话总结:

  • 新项目:JDK 21 + Eclipse Temurin
  • JDK 8老项目:规划升级到17,再升21
  • JDK 11项目:今年升到21(免费维护即将结束)
  • 发行版:Temurin或Corretto
  • 版本管理:Docker + SDKMAN + .java-version

JDK的更新节奏确实快,但这也是Java保持活力的原因。不要被版本号吓到——每一步升级都有明确的收益,尤其是虚拟线程,值得你认真尝试。

从JDK 8到JDK 21,不只是版本号的跳动,是整个编程范式的升级。早一天切换,早一天受益。


发布于 程序员ShimonXin