Java 14都快出来了,为什么还有那么多人执着于Java 8?

升不动啊。

Java 9 的模块系统直接把一堆框架干趴了,升上去项目跑不起来,降回来一切正常。试过一次之后大多数团队的结论都一样:别动了。

升 Java 9 的第一件事:控制台开始刷红

Java 9 加了个模块系统(JPMS),把 JDK 内部的包封起来了。

之前框架随便用反射访问 sun.reflect.*com.sun.* 这些内部类。文档虽然写着”非公开 API,请勿使用”,但能用、好用、还快,用了十几年,谁当它是非公开的?

Java 9 直接不让用了。升上去之后,控制台开始刷:

Java 16 之后,警告直接变成异常,程序直接崩。

Hibernate、Jackson、Spring 里用反射扒 JDK 内部的地方全撞上了。各种框架紧急发版,JVM 启动参数里开始出现一堆 --add-opens

--add-opens java.base/java.lang=ALL-UNNAMED
--add-opens java.base/java.util=ALL-UNNAMED
--add-opens java.base/sun.nio.ch=ALL-UNNAMED

意思就是:把刚封上的门重新撬开,告诉 JVM”这里允许非法进入”。

大部分公司的选择很朴素:Java 9 升上去一堆东西要修,那不升了,Java 8 好好的,别动。

升个 Java 版本,结果整条工具链都得跟着动

加几个 --add-opens 还好说。头疼的是不知道哪里还藏着问题。

Lombok 就是典型。它通过 Annotation Processor 在编译期修改 AST(抽象语法树),深度依赖编译器内部 API。模块系统限制了这些 API 的访问,Lombok 每次 Java 大版本更新都要追着修。有时候编译能过、跑不起来;有时候 IDE 没事、CI 报错,玄学问题一堆。

Jacoco(代码覆盖率工具)、Byte Buddy(字节码增强库,MyBatis、Mockito 底层都在用)、ASM,这些做字节码操作的工具在 Java 9 前后都有过一段动荡期,不升到对应版本就各种奇怪报错。

一个中型项目,几十个直接依赖,每个依赖背后还有一堆传递依赖。有没有哪个传递依赖在 Java 11 上跑不起来?不试不知道。QA 测不覆盖所有场景,上线出问题就是事故。

换来的收益呢?GC 改进、性能微调、var 关键字?跟出故障的风险比,划不来。

写 CRUD 的话,Java 8 真的够了

代价大是一回事,关键 Java 8 对大多数人来说,真的够了。

Java 7 遍历一个列表,过滤出满足条件的元素:

List<String> result = new ArrayList<>();
for (String s : list) {
    if (s.startsWith("A")) {
        result.add(s);
    }
}

Java 8 之后:

List<String> result = list.stream()
    .filter(s -> s.startsWith("A"))
    .collect(Collectors.toList());

写过 Java 7 的人都记得那种感觉——Lambda 出来之后不想回去了。并行处理、懒加载、链式调用,Java 7 里要么写一大堆代码,要么引 Guava,Java 8 直接内置。

再加上 Optional 治空指针、CompletableFuture 做异步编排、LocalDateTime 替掉折磨人的 Calendar,Java 8 一口气解决了日常开发里最烦的几个问题。

升到 Java 9-14 呢?var 类型推断(省几个字),文本块(多行字符串好看点),List.of() 创建不可变集合,switch 表达式改进。

有用,但没有 Lambda 那种”用了就回不去”的冲击。日常写 CRUD,Java 8 的 API 绑着眼睛都够用,升级的迫切感就是上不来。

半年一个版本,追都不知道追哪个

Java 8 到 Java 9,隔了三年半。Java 9 之后,Oracle 改成每半年发一个版本:9、10、11、12、13、14……版本号像坐了火箭。

大多数人直接懵了:要跟着升吗?追到哪个?

后来慢慢有了共识:只有 LTS(长期支持)版本值得跟——Java 8、11、17、21。非 LTS 版本只有 6 个月支持期,企业没人敢用。

但形成这个共识需要时间。版本号一路飙,第一反应就是”迭代这么快,还没稳定,先观望”。这一观望,就在 Java 8 上又多待了好几年。

还有个现实问题:谁提升级谁背锅

Java 8 跑了五年,没出过和 Java 版本相关的线上事故。现在有人提议升 Java 17,出发点是”享受新特性”。出了问题怎么说?

“我们把 Java 从 8 升到 17,然后出了一个不明原因的 bug。”

不管最后 root cause 是不是升级导致的,提议升级的那个人都得兜着。

而不升的理由天然充分:”系统运行稳定,升级风险大于收益,暂不处理。”——写进周报里没人挑毛病。

说白了就是风险收益算不过来。安全漏洞没爆、框架还能用,谁会主动去折腾?

不过现在不升也不行了

Java 8 的 Oracle 商业支持已经结束,OpenJDK 各发行版的公共更新也停了。继续用 Java 8 意味着安全漏洞不再有官方补丁。

更大的推力是 Spring Boot 3.x——最低要求 Java 17,没得商量。Spring Boot 2.x 已经停止维护了,不再有安全更新。还守着 Spring Boot 2.x + Java 8 的项目,等于在裸奔。

如果要升,建议从 Java 8 直接跳 Java 21。同样是 LTS,而且带了真正值得升的东西:虚拟线程(高并发场景下性能碾压传统线程池)、Records(数据类不用手写 getter/setter/equals/hashCode)、Pattern Matching、Sealed Classes。

从 8 跳 11 再跳 17 再跳 21,每次升级都要排查一轮兼容性。不如一步到位跳 21,只踩一次坑。

编辑于 2026-04-03 · 著作权归作者所有