IntelliJ IDEA中需统一Project SDK、language level和bytecode version;Eclipse中Compiler compliance level须≤Generated class files compatibility;Maven用替代/避免API越界;IDE设置不影响命令行javac,需单独配置环境变量。

IDEA 里怎么改 Java 编译器版本
IntelliJ IDEA 默认用项目 SDK 的 JDK 版本编译,但 Project bytecode version 和 Target bytecode version 可能不一致,导致编译通过、运行报 java.lang.UnsupportedClassVersionError。
操作路径:File → Project Structure → Project,确认三项统一:
-
Project SDK:选对已安装的 JDK(如17) -
Project language level:应与 SDK 匹配(如17 (Preview) - Switch expressions, pattern matching...) -
Project bytecode version:默认跟随 language level,但可手动下调(如设为11以兼容旧 JRE)
注意:仅改 Project SDK 不等于自动适配字节码;若模块独立配置了 Language level(在 Modules 页签),会覆盖全局设置。
Eclipse 中 target compliance 和 compiler compliance 的区别
Eclipse 有两个关键选项:Compiler compliance level 决定语法和 API 检查(如是否允许 var、record),而 Generated class files compatibility(即 target compliance)控制生成的 .class 文件主版本号。
立即学习“Java免费学习笔记(深入)”;
常见错误现象:代码用了 switch 表达式(Java 14+),但 Generated class files compatibility 设为 1.8 → 编译失败,报 Switch expressions are not supported at language level '8'。
正确做法:
- 两者必须满足:
Compiler compliance level ≤ Generated class files compatibility - 若要生成可在 JDK 11 上运行的 class,
Generated class files compatibility必须 ≤11,且Compiler compliance level不能高于11 - 修改位置:Preferences → Java → Compiler
Maven 编译插件里 source 和 target 参数的实际作用
maven-compiler-plugin 的 和 并非“源码版本”和“目标 JVM 版本”的简单映射,它们影响三件事:语法解析、API 可见性、字节码生成版本。
例如:
org.apache.maven.plugins maven-compiler-plugin 3.11.0 17 17
这表示:允许使用 Java 17 语法(如 sealed classes)、只调用 JDK 17 及以下的 public API、生成 class 文件主版本号为 61(对应 Java 17)。
容易踩的坑:
-
❌ 非法:Maven 插件会拒绝,报错17 11 Source option 17 is not compatible with target option 11 - 仅设
更安全:它隐式启用11 --source 11 --target 11 --bootclasspath,避免意外引用高版本 API - 若用 JDK 21 编译但需运行在 JDK 17 上,应设
,而非17 21 17
为什么改了 IDE 编译设置,但 javac 命令行编译还是失败
IDE 的编译器设置只影响 IDE 内部构建流程,不影响终端中手动执行的 javac。如果你在命令行运行 javac Main.java 报错,那完全是本地 JDK 和环境变量的事。
检查顺序:
- 运行
javac -version和java -version,确认二者版本一致 - 检查
$JAVA_HOME是否指向预期 JDK(如/usr/lib/jvm/java-17-openjdk-amd64) - 确认
PATH中$JAVA_HOME/bin在系统自带javac(如 Ubuntu 的/usr/bin/javac)之前 - 若用 SDKMAN!,执行
sdk use java 17.0.2-tem再试
IDE 编译成功 ≠ 命令行能编译成功——这是两个完全独立的工具链,别混淆。










