JDK选择核心是匹配运行时环境与依赖生态,JDK 17(LTS)为当前最稳妥起点;Spring Boot 3.x或Jakarta EE 9+必须用JDK 17+,老系统若依赖Java 8专属库则不宜升级。

Java项目选JDK,核心不是“最新”,而是“匹配运行时环境与依赖生态”——JDK 17(LTS)是当前最稳妥的起点,但若用Spring Boot 3.x或Jakarta EE 9+,必须用JDK 17及以上;若维护老系统且依赖大量Java 8专属库(如某些Oracle JDBC驱动旧版),JDK 8仍不可贸然升级。
怎么看项目实际依赖的最低JDK版本
不能只看IDE里装了哪个JDK,关键要查三处:
-
pom.xml中或maven-compiler-plugin的/(如设为11,编译产物就无法在JDK 8上运行) - 第三方库的
MANIFEST.MF或其官方文档——例如netty-4.1.90.Final明确要求 JDK 8+,而quarkus-bom-3.0.0要求 JDK 17+ - 运行环境约束:Docker基础镜像(如
eclipse-jetty:9-jre8)或云平台(如阿里云EDAS旧版仅支持JDK 8)会硬性卡住上限
JDK 8、11、17、21 这几个LTS版本的关键差异点
不是功能越多越好,而是哪些特性你真用得上、哪些变更会破环现有逻辑:
- JDK 8:
Optional刚引入,StreamAPI 基础可用,但无Map.of()、String.isBlank();javax.*包全量存在——适合老系统维稳 - JDK 11:移除
Java EE和Corba模块,HttpClient变为标准API;jlink可裁剪JRE;但部分国产中间件(如东方通TongWeb 6.x)需打补丁才兼容 - JDK 17:
sealed classes、Pattern Matching for switch(预览转正式);SecurityManager被弃用;Spring Boot 3.x 默认要求此版本 - JDK 21:虚拟线程(
Thread.ofVirtual())正式落地,GC新增ZGC低延迟模式;但GraalVM原生镜像对部分反射-heavy框架(如Lombok + MapStruct组合)仍有兼容问题
升级JDK时最容易被忽略的三个坑
编译通过 ≠ 运行正常,这些地方常在上线后暴雷:
立即学习“Java免费学习笔记(深入)”;
-
sun.misc.BASE64Encoder在JDK 16+中彻底移除,必须替换成java.util.Base64;搜索代码里所有sun.*引用,它们都不是公共API - 默认TLS协议变化:JDK 11+禁用TLS 1.0/1.1,若调用的老旧银行接口只支持TLS 1.1,需显式配置
-Djdk.tls.client.protocols=TLSv1.1,TLSv1.2 - 类加载顺序微调:JDK 9+模块系统启用后,
ClassLoader.getSystemResources("META-INF/MANIFEST.MF")返回顺序可能变,影响某些基于SPI自动发现的框架(如旧版Shiro)
版本选择本质是权衡:新JDK带来性能和语法糖,但也抬高团队认知成本和运维复杂度。真正卡住升级的往往不是语言特性,而是那几个没写文档的私有API调用、某台物理机上跑着的JDK 7容器、或者客户合同里白纸黑字写的“必须支持Windows Server 2008 R2”——这些细节比版本号本身更值得花时间确认。










