登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  java教程

Java 25 升级后怎样检查预览特性开关

来源:17golang原创

时间:2026-11-03 11:03:09 439浏览 收藏

Java 25 升级后,预览特性的检查重点不是“版本号有没有变成 25”,而是编译阶段和运行阶段是否都使用了同一套预览开关。实际排查可以压缩成 3 个基线检查点、2 个开关阶段和 4 格结果矩阵:先看 java 与 javac,再看 javac 是否带 --enable-preview,最后看 java 启动时是否再次带上它。

官方地址:https://docs.oracle.com/en/java/javase/25/

只要代码依赖 Java 25 的预览特性,javac 需要把 --enable-preview 与 --release 25(或匹配的 --source)一起使用;生成的 class 启动时还要让 java 再次看到 --enable-preview。少任意一段,升级检查都不能算完成。

一、先把升级后的基线记录成三个检查点

我在迁移时不会直接改构建脚本,而是先把版本基线留下来。原因很简单:终端里的 java 可能已经切到 25,但 javac 仍然来自旧 JDK;也可能本地是 25,CI 的启动器还是另一个版本。基线至少包含运行时、编译器和预览能力提示三个检查点。

# 检查运行时版本,确认启动应用的 java 已切换
java -version

# 检查编译器版本,避免 javac 仍来自旧 JDK
javac --version

# 查看编译器是否提供预览开关,输出只作为能力线索
javac --help-extra | grep -- --enable-preview

这里的数字不是性能指标,而是迁移证据:3 个检查点全部有记录,后面的编译和运行结果才有可比性。如果 java、javac 的主版本不一致,先修复 JDK 路径或 CI 镜像,再判断预览开关。

二、先区分“预览特性”和“已经转正的特性”

Java 25 并不是所有新增语言能力都需要开关。Oracle 的 Java SE 25 语言变更表把 Module Import Declarations、Compact Source Files and Instance main Methods、Flexible Constructor Bodies列为永久特性;仍处于预览状态的是 JEP 507“Primitive Types in Patterns, instanceof, and switch”第三次预览。

检查对象Java 25 状态是否检查 --enable-preview
Primitive Types in Patterns、instanceof、switch预览语言特性编译和运行都需要
Module Import Declarations永久特性不因它单独开启
Flexible Constructor Bodies永久特性不因它单独开启
预览 API按对应 API 文档判断编译和运行按契约处理

这一步能避免一个常见误判:看到 Java 25 有新语法,就把整个项目标成 preview。正确做法是先按官方变更表确认特性状态,再让构建脚本只为确实使用预览能力的模块开启开关。

三、编译检查:--enable-preview 必须和 release 绑定

javac 文档明确说明,--enable-preview 要和 --release 或 --source 配合使用。对 Java 25 的预览代码,优先把目标版本写成 --release 25,这样源语言、目标 class 和对应 API 版本在同一个契约里。

# 编译 Java 25 预览代码,版本和预览开关必须同时出现
javac --release 25 --enable-preview -d out src/PreviewSample.java

# 多文件项目也沿用同一组编译参数,避免模块之间状态不一致
javac --release 25 --enable-preview -d out src/*.java

如果只写 --enable-preview 而没有 --release 或 --source,命令本身就不符合编译器的参数契约;如果把 --release 写成旧版本,则预览能力对应的语言和 API 范围也会错位。

Java 25 预览特性编译器、release、preview 开关和 class 文件的静态边界图
图1:Java 25 预览特性在编译阶段与运行阶段的静态边界说明图;它用于理解开关归属,不是运行截图。

四、运行检查:JVM 启动阶段也要再次开启预览

编译成功只说明 javac 接受了预览语法,不代表 JVM 会加载这些 class。运行时需要再给 java 一次 --enable-preview,这是第二个独立检查点。

# 运行刚才生成的 class,JVM 也必须显式启用预览
java --enable-preview -cp out PreviewSample

# 如果交付的是 JAR,把开关放在 -jar 之前
java --enable-preview -jar build/app.jar

只编译时开启、启动时遗漏,常见结果是 JVM 在加载 class 时提示预览特性未启用。这个错误发生在运行入口,不应被误判成业务逻辑异常;检查启动脚本、容器参数和 IDE 的 Run Configuration 是否把同一开关传给了 JVM。

如果使用的是 Java 25 预览的 primitive pattern,可以把示例代码替换成项目中的真实最小样例。重点不是样例复杂度,而是让同一个 class 经过“带开关编译”和“带开关启动”两次明确检查。

五、用四格检查矩阵定位升级遗漏

迁移时最省时间的方法,是把“编译开关”和“运行开关”拆成两列,不要用一次成功的本地命令代替整个判断。下面四格覆盖了最常见的升级结果:

预览源代码编译阶段运行阶段结论
否不需要 preview不需要 preview普通 Java 25 代码
是有 --release 25 --enable-preview有 --enable-preview完整链路
是缺编译开关有运行开关编译阶段先失败
是编译成功缺运行开关加载 class 时失败

这张表给出的结果是可复现的判断逻辑,不是我替读者虚构的运行日志。把四格写进 CI 或迁移清单后,升级问题会从“Java 25 不兼容”收敛成“哪一个阶段缺了开关”。

Java 25 预览开关四格检查矩阵与编译运行结论的静态关系图
图2:Java 25 预览开关四格检查矩阵的静态说明图;它展示判断维度,不是 CI 截图或运行证据。

六、把检查结果固化到构建和启动脚本

如果只有开发者本地命令带开关,下一次发布仍然会丢。建议把 Java 25 的版本和 preview 参数放在同一个构建 profile 或脚本变量里,并让编译与启动分别显式引用。

# 在 CI 中集中声明版本,避免编译器和启动器各写一套
JAVA_RELEASE=25
PREVIEW_FLAG=--enable-preview

# 编译阶段绑定 release 与 preview
javac --release "$JAVA_RELEASE" "$PREVIEW_FLAG" -d out src/PreviewSample.java

# 运行阶段再次传递 preview,不能复用编译阶段的隐式状态
java "$PREVIEW_FLAG" -cp out PreviewSample

正式环境是否使用预览能力,要由项目的兼容性策略决定。预览特性仍可能在后续版本中调整或撤回,升级时必须重新阅读对应版本文档、重新编译,不能把旧版本生成的预览 class 当作跨版本构件长期复用。

七、常见问题

只执行 java -version 能确认预览开关吗?

不能。它只能说明当前调用到的运行时版本,不能证明编译器参数、class 文件来源和启动参数都正确。至少还要记录 javac --version、编译命令和运行命令。

Java 25 的永久特性还要加 --enable-preview 吗?

不需要因为“它是 Java 25 新特性”就自动开启。先按官方语言变更表判断;已经转正的特性按普通 Java 25 源码编译,只有真正使用预览语言或预览 API 时才按对应契约处理。

本地能跑,CI 却提示 preview 未启用怎么办?

按四格矩阵分别检查 CI 的 javac、构建参数、java 启动参数和容器入口。最常见的差异是构建插件接收了 --enable-preview,但测试任务或生产启动命令没有接收。

总结

Java 25 升级后的预览开关检查可以固定成一条短路径:先记录 3 个版本/能力基线,再确认目标特性是不是预览,之后在编译阶段用 --release 25 --enable-preview,在运行阶段再次使用 --enable-preview,最后用 4 格矩阵定位遗漏。这样检查的对象是开关所在的阶段,结论才不会停留在“版本已经升级”的表面。

参考资料:

  • https://docs.oracle.com/en/java/javase/25/language/java-language-changes-summary.html
  • https://docs.oracle.com/en/java/javase/25/migrate/significant-changes-jdk-25.html
  • https://docs.oracle.com/en/java/javase/25/docs/specs/man/javac.html
  • https://docs.oracle.com/en/java/javase/25/docs/specs/man/java.html
声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>