上个月,JDK 25 正式发布。

我在某技术社区看到一个帖子,几百条评论里,点赞最高的那条就六个字:

“你发任你发,我用 Java 8。”

笑完,我想认真聊聊这件事。

从 2014 年到现在,Java 8 已经 12 岁了。而它依然是绝大多数公司生产环境的主力版本。

根据 New Relic 2024 年 Java 生态报告,Java 17 虽然已成用量第一的 JDK,但占比还没过半。Java 8 加 Java 11,仍然握着相当规模的存量市场。在国内,这个数字会更高——很多中小企业和传统行业的核心系统,稳稳跑在 Java 8 上,这不是夸张。

JDK 都出到 25 了,Java 8 为什么还这么难消灭?


"向下兼容"是个美丽的谎言

很多人以为 Java 升级很简单,因为 Java 一向强调向后兼容。语法上确实没什么大变化,你在 Java 8 里写的代码,理论上在 Java 25 里也能编译。

但问题来了:编译通过,不等于行为一致。

从 JDK 9 开始,Java 引入了模块化系统(JPMS),对 JVM 内部的类做了强封装。以前很多框架和工具库会通过反射去访问 JVM 内部字段,比如 String.value,或者一些序列化框架依赖的私有字段。Java 8 里这些访问是允许的,但到了 JDK 9+,你会看到 InaccessibleObjectException,直接运行报错。

更棘手的是运行时行为变化。GC 策略变了,JIT 优化路径变了,内存分配的默认行为也变了。这些变化在测试环境里不一定复现,但在高并发的生产环境里,可能就是一个神秘的偶发故障,排查三天查不出原因。

所以,真正的升级代价不是改几行代码,而是你要对整个系统的运行时行为重新建立信心——而这件事,没有捷径。


真正拖住升级的,是那些"不敢动"的地方

升级失败的团队,通常不是败在 Java 语法层面,而是败在依赖链上。

一个典型的老项目依赖结构大概是这样的:Spring Boot 2.x + 一堆四五年没更新的第三方 jar,其中有几个已经找不到维护者了,有几个在 Java 11 上就没经过测试。你升级了 JDK,但这些包还在,它们能不能正常工作,没有人敢拍胸脯说"没问题"。

还有一类更隐蔽的问题:代码里有大量"没人敢动"的模块。注释写的是"此处逻辑复杂,勿轻易修改",原作者已经离职,没有文档,测试覆盖率接近零。升级 JDK 这个外部变量一进来,这些模块就是定时炸弹。

所以,很多时候你以为在逃避的是 JDK 升级,实际上你在逃避的是整个系统的技术债。 升级只是把账单从抽屉里拿了出来,而不是它产生了新的欠债。


逼你升级的,从来不是技术本身

很多人以为技术进步会自然推动升级,但现实并不是这样运作的。

JDK 21 的虚拟线程(Virtual Thread)很香,理论上能让你用同步代码的写法实现高并发,省掉一大堆线程池调优的麻烦。JDK 17 的 ZGC 低延迟垃圾回收器也很香,P99 延迟控制在毫秒以内。这些特性很强,但对于一个稳定运行的老系统来说,"现在能用"永远不是升级的理由——"必须用"才是。

真正推动企业升级的,往往是几件具体的事:

安全漏洞逼你动手。 Oracle 对 Java 8 的免费公开更新已于 2019 年停止(商业支持延至 2030 年),这意味着新的安全漏洞可能没有免费补丁。金融、医疗、政企,这些对安全合规有硬性要求的行业,这张账单迟早要交。

供应链开始甩你。 Spring Boot 3.x 要求 JDK 17 作为最低版本,不少新兴中间件和云原生组件也陆续放弃对 Java 8 的官方支持。当你的技术栈里有个重要组件宣布"不再支持 Java 8",升级就从"可选项"变成了"必选项"。

招人开始出问题。 你在 JD 里写"Java 8 开发经验优先",你能吸引到的候选人画像,可能已经说明了一些问题。


Java 8 到 Java 25,这十二年你错过了什么

如果只是为了稳定,停在 Java 8 没什么问题。但如果你想知道这十二年里 Java 到底进化了什么,下面几点值得了解:

Lambda 之后的函数式进化(Java 9-16):Stream API 增强、Optional 更好用、var 局部类型推断、record 类型(不用再写十几行 POJO)、sealed class(更精确的类型约束)、Switch 表达式重写——这些特性单独拿出来都不是颠覆性的,但组合起来,代码的简洁度和表达力有质的提升。

性能层的重大升级(Java 11-21):ZGC 和 Shenandoah 带来了低延迟 GC;G1 GC 的成熟让大多数场景无需手动调优;JDK 17 的整体性能相比 JDK 8 在多核场景下提升明显。

并发编程的范式升级(Java 21):虚拟线程正式转正,让每请求一线程的编程模型重新变得可行。对 IO 密集型服务来说,这意味着你可以以极低成本处理数万并发连接,而不用引入响应式编程的心智负担。

JDK 25 的亮点:值类型(Value Types,Project Valhalla 落地)初步成形,内存布局更紧凑,有望改善数值计算密集型场景的性能;模式匹配进一步完善,代码表达力再上一个台阶。


升不升,怎么升

讲了这么多,给几个实际的建议:

新项目:直接 JDK 21。 Java 21 是当前最新的 LTS 版本,支持周期长,生态成熟,Spring Boot 3.x、Quarkus、Micronaut 全系支持。没有理由在 2026 年还选 Java 8 起新项目。

老项目:不要一刀切升级,要找驱动力。 如果系统稳定、没有安全合规压力、关键依赖还在维护,Java 8 能用就先用。但如果依赖链开始出现"不支持 Java 8"的警告,或者有安全审计要求,那就按模块分批迁移,先升测试环境,跑 3 个月再切生产。

迁移工具值得用。 OpenRewrite 是目前最成熟的 Java 代码自动迁移工具,可以批量处理 javaxjakarta 这类机械性迁移,省掉大量手工改代码的工作。

最重要的一点:先搞清楚你真正的障碍在哪。 很多团队一提升级就头大,但细追下去,真正的问题往往不是 JDK 本身,而是那些年久失修的内部组件、缺失的测试覆盖、或者没有人愿意牵头推动的组织问题。把这些问题搞清楚,比讨论"该不该升"更有价值。


最后说一句

Java 生态的兼容性设计,让你可以"一直不升"。但这个"一直不升"背后,是每一年悄悄堆起来的技术债,和每一年悄悄关上的新特性大门。

JDK 25 已经在了。你不一定要升,但你得知道,你在为什么选择不升。

你们公司现在用的哪个版本?卡在哪儿了?欢迎留言,我们聊聊。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐