jdk 17 是新项目唯一合理起点,spring boot 3.x 强制要求,支持 record、sealed、zgc 等关键特性;老系统升级需警惕 javax.* 依赖、模块化冲突及 gc/https 兼容性问题,且须统一开发、ci、容器三端 jdk 版本。

老系统还在用 Spring Boot 2.7 或 Shiro?别硬升 JDK 17
直接卡在 java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlRootElement 或 ClassNotFoundException: org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter 是最常见的升级失败现场。Shiro 1.4、Struts2 2.5、甚至部分银行私有 SDK,底层强依赖 javax.* 包和 JDK 8 的类加载机制,JDK 9+ 的模块系统一启动就崩。
- 确认框架真实支持范围:运行
mvn dependency:tree | grep spring-boot查出版本,再查对应文档的 Supported JDK Versions 表,别信“理论上兼容” - 如果用了
javax.xml.bind、javax.activation,JDK 17 下必须显式加jakarta.xml.bind-api和jakarta.activation-api,且注意 Jakarta 命名空间迁移 - Spring Boot 2.7.x 虽然文档说“支持 JDK 17”,但部分补丁版对 JDK 17 的 TLS 1.3 握手或 G1 GC 参数实际存在兼容问题,上线前务必压测 HTTPS 接口和连接池行为
新项目起步或 Spring Boot 3.x 选型?JDK 17 是唯一合理起点
2026 年还为新服务选 JDK 8,等于主动放弃 record、sealed、switch 模式匹配这些能减少空指针、约束继承链、提升可读性的语言能力;也意味着你得自己配 ZGC、写一堆 Optional 套娃,而不是用一行 if (obj instanceof String s) { ... } 安全解构。
- Spring Boot 3.0+ 强制要求 JDK 17+,连编译都过不去,不是“建议”而是硬门槛
- JDK 17 的 ZGC 和 Shenandoah GC 开箱即用,堆设到 16GB 以上也不怕 STW,比 JDK 8 默认的 Parallel GC 更适配云原生弹性伸缩场景
- record 类自动实现
equals/hashCode,密封类(sealed)配合permits明确子类白名单——这些不是语法糖,是降低维护成本的基础设施
本地开发、CI/CD、容器镜像三端 JDK 版本不一致?构建失败只是时间问题
开发者用 IDEA 里装了 JDK 21 写了个 sealed class Shape permits Circle, Rect {},CI 流水线却跑在 Jenkins 节点的 JDK 17 上,报错 error: illegal combination of modifiers: sealed and final——这不是环境问题,是流程漏洞。
-
maven-compiler-plugin的<source></source>和<target></target>必须显式锁定,比如设为17,防止本地误用高版本语法 - GitHub Actions 用
actions/setup-java@v4指定java-version: '17';Jenkins 则必须在节点配置中绑定具体 JDK Home,不能只写 “JDK 17” 这种模糊名称 - Dockerfile 中别写
FROM openjdk:17-jre-slim就完事,要核对基础镜像来源:Eclipse Temurin、Amazon Corretto、Azul Zulu 对虚拟线程或 JFR 支持有细微差异,生产环境优先选 Temurin 或 Corretto
性能宣传别轻信:JDK 17 vs JDK 21 的 GC 和线程收益要看 workload
“JDK 21 吞吐提升 10%” 这类说法,基本来自 SPECjbb 基准测试,跟你的订单服务、风控规则引擎、实时日志聚合完全不是一回事。小对象高频创建的服务,ZGC + JDK 21 确实延迟更稳;但 IO 密集型应用开启虚拟线程(VirtualThread)后,调度开销反而可能推高 P99 延迟。
立即学习“Java免费学习笔记(深入)”;
- 别为了“新”而切 JDK 21:它虽是 LTS,但虚拟线程生态(如 Spring Boot 对
TaskScope的支持)仍处于灰度阶段,线上大规模使用需谨慎评估 - JDK 17 的 G1 GC 参数已足够成熟,
-XX:+UseG1GC -XX:MaxGCPauseMillis=200配合合理堆大小,覆盖 90% 的企业级业务场景 - 真正影响性能的往往不是 JDK 版本,而是
-Xms/-Xmx是否等值、是否禁用System.gc()、JVM 启动参数是否与容器内存限制对齐










