Java多版本共存应使用SDKMAN!工具链隔离而非硬改环境变量,它通过shell hook动态注入临时JAVA_HOME,支持跨平台JDK安装、会话级切换及IDE、Maven、运行配置的独立指定,并需在构建脚本中显式声明版本以避免厂商差异导致的问题。

Java 多版本共存不是靠改系统环境变量硬切,而是用工具链隔离 + 显式声明运行时,否则 JAVA_HOME 冲突、java -version 和 javac -version 不一致、Maven 编译失败等问题会反复出现。
用 SDKMAN! 统一管理 JDK 安装与切换
SDKMAN! 是目前最轻量、跨平台(Linux/macOS/WSL)且对 Java 生态支持最稳的版本管理器,它不修改全局 JAVA_HOME,而是通过 shell hook 注入临时环境变量,每个终端会话可独立指定 JDK。
常见错误:手动下载多个 JDK 解压后硬写 export JAVA_HOME=... 到 ~/.bashrc,结果新开终端全乱套,IDE 读不到,CI 脚本也不生效。
- 安装:
curl -s "https://get.sdkman.io" | bash
,然后重启 shell 或执行source "$HOME/.sdkman/bin/sdkman-init.sh" - 列出可用 JDK:
sdk list java(会显示temurin-17.0.2+8、zulu-11.0.22+3等带厂商和构建号的完整标识) - 安装指定版本:
sdk install java 17.0.2-temurin(注意用列表里显示的精确 ID,不是简单写17) - 设为当前会话默认:
sdk use java 17.0.2-temurin;设为全局默认:sdk default java 17.0.2-temurin
在 IDE(IntelliJ IDEA / Eclipse)中绑定项目级 JDK
IDE 不读 SDKMAN! 的 shell 环境,必须显式配置。否则即使终端里 java -version 正确,IDE 编译仍可能用错 JDK 或报 Unsupported class file major version。
立即学习“Java免费学习笔记(深入)”;
关键点:项目 SDK ≠ 全局 JDK ≠ Maven JDK ≠ 运行配置 JDK —— 四者要分别确认。
- IntelliJ:File → Project Structure → Project → Project SDK → 点击
New… → JDK,选 SDKMAN! 安装路径下的具体目录(如~/.sdkman/candidates/java/17.0.2-temurin) - 同时检查 Modules → Language level(决定语法支持,如
record需要 14+)、Project compiler output path - Maven 配置:Settings → Build → Build Tools → Maven → Importing → JDK for importer(影响
pom.xml解析),以及 Runner → JRE(影响mvn compile执行时的 JDK) - 运行配置:Edit Configurations → Templates → Application → JRE(控制你点 ▶️ 运行时实际用的 JDK)
在构建脚本中硬编码 JDK 路径或版本标识
CI/CD 流水线或本地自动化脚本若依赖 $JAVA_HOME,而该变量又由 SDKMAN! 动态设置,就容易因 shell 初始化缺失导致 fallback 到系统默认 JDK(比如 macOS 自带的 /usr/bin/java)。
解决方案不是“修环境变量”,而是让构建工具自己找 JDK。
- Maven:在
pom.xml中用maven-compiler-plugin显式声明源码和目标字节码版本:org.apache.maven.plugins maven-compiler-plugin 3.11.0 17 17 - Gradle:在
build.gradle中设置java.toolchain.version = "17",Gradle 17+ 会自动匹配已安装的 JDK 17 - Shell 脚本中避免直接调用
java,改用 SDKMAN! 提供的sdk env生成临时环境:sdk env java 17.0.2-temurin && java -version
最常被忽略的是:不同 JDK 厂商(Temurin、Zulu、Corretto)虽都标称 “JDK 17”,但它们的 java --version 输出格式、内置 JVM 参数默认值、甚至某些 JNI 行为都有差异。线上部署前务必用和生产环境同源的 JDK 构建并验证。










