摘要本文介绍如何在 Mac 上安装和管理多个 JDK 版本。文章从使用 Homebrew 安装 Azul Zulu 8 和 Eclipse Temurin 17 入手详细讲解JAVA_HOME环境变量的作用以及如何通过/usr/libexec/java_home工具查看和切换 JDK 版本。随后介绍配置java8、java17快捷命令的方法并进一步推荐使用jenv实现按项目自动切换 Java 版本。最后梳理JAVA_HOME、PATH和java -version三者之间的关系帮助读者根据自身情况选择合适的管理方案。1. 安装brew install --cask zulu8 brew install --cask temurin17其中brew install → 使用 Homebrew 安装 --cask → 安装厂商提供的 macOS 软件包 temurin → Eclipse Temurin JDK 17 → Java 17Temurin 是什么Eclipse Temurin是 Eclipse Adoptium 项目推出的 OpenJDK 发行版。它和我们刚才提到的 Azul Zulu 属于同一类东西OpenJDK │ ┌────────────┼─────────────┐ ↓ ↓ ↓ Eclipse Azul Amazon │ │ │ Temurin Zulu Corretto │ │ Temurin 17 Zulu 17所以brew install --cask temurin17你可以把它直接理解成在 Mac 上安装 Eclipse 提供的 OpenJDK 17 JDK。它安装的不只是javaJDK 是完整的 Java 开发工具包安装完成后通常会包含JDK 17 ├── java ← 运行 Java 程序 ├── javac ← 编译 Java ├── jar ← 操作 jar 包 ├── javadoc ├── jcmd ├── jps └── JVM 等安装完成可以java -version看到类似openjdk version 17.x.x OpenJDK Runtime Environment Temurin-17... OpenJDK 64-Bit Server VM Temurin-17...还可以javac -version确认编译器javac 17.x.x和zulu8是什么关系这两个命令其实非常适合放一起理解brew install --cask zulu8 brew install --cask temurin17区别主要就是命令JDK 发行商/项目Java 版本zulu8Azul ZuluJava 8temurin17Eclipse TemurinJava 17所以你甚至可以在同一台 Mac 上同时安装Zulu 8 Temurin 17然后不同项目使用不同 JDK。例如老项目Project A ↓ Java 8 ↓ Zulu 8新一点的项目Project B ↓ Java 17 ↓ Temurin 17这时候真正需要注意的是JAVA_HOME当前到底指向 Java 8 还是 Java 17。你可以运行/usr/libexec/java_home -V查看 Mac 上安装的所有 JDK。你现在已经知道 Mac 上可以同时装JDK 8 → Azul Zulu 8 JDK 17 → Eclipse Temurin 17接下来最关键的就是理解“安装了哪些 JDK”和“当前正在使用哪个 JDK”是两回事而JAVA_HOME就是控制后者的重要变量。2.JAVA_HOMEJAVA_HOME是一个环境变量它的值指向某个 JDK 的安装目录。例如echo $JAVA_HOME可能得到/Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home意思就是当前环境告诉 Java 相关程序“我的 JDK 在这里。”很多开发工具都会读取它例如Maven Gradle Tomcat Spring Boot Android 构建工具 各种 Java CLI可以理解成JAVA_HOME │ ▼ 当前指定的 JDK 安装目录 │ ┌─────────┴─────────┐ ↓ ↓ bin/java bin/javac 运行 Java 编译 Java3. Mac 中 JDK查看执行/usr/libexec/java_home -V假设你安装了刚才说的两个版本可能看到类似Matching Java Virtual Machines (2): 17.x.x (arm64) Eclipse Adoptium OpenJDK 17 /Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home 1.8.0_xxx (arm64) Azul Systems, Inc. Zulu 8 /Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home也就是Mac │ ├── Zulu JDK 8 │ └── Temurin JDK 174./usr/libexec/java_home很有用Mac 自带一个工具/usr/libexec/java_home它可以帮你找到 JDK。例如找 Java 17/usr/libexec/java_home -v 17可能返回/Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home找 Java 8/usr/libexec/java_home -v 1.8返回类似/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home所以我们没必要自己把这些长路径写死。切换到 Java 8执行export JAVA_HOME$(/usr/libexec/java_home -v 1.8)然后java -version应该看到 Java 8。再检查echo $JAVA_HOME会看到类似/Library/Java/JavaVirtualMachines/zulu-8.jdk/Contents/Home切换到 Java 17同理export JAVA_HOME$(/usr/libexec/java_home -v 17)然后java -version应该变成openjdk version 17...所以最基本的切换其实就是# Java 8 export JAVA_HOME$(/usr/libexec/java_home -v 1.8) Java 17 export JAVA_HOME$(/usr/libexec/java_home -v 17)为什么改JAVA_HOME后java也会跟着变这里有个容易忽略的问题严格来说export JAVA_HOME...并不等于修改了java命令。Shell 执行java主要还是通过PATH寻找java。所以比较完整的配置通常是export JAVA_HOME$(/usr/libexec/java_home -v 17) export PATH$JAVA_HOME/bin:$PATH这样JAVA_HOME ↓ Temurin JDK 17 ↓ $JAVA_HOME/bin ↓ 放到 PATH 最前面 ↓ java / javac ↓ 使用 Java 17检查which java以及java -version javac -version echo $JAVA_HOME这几个命令结合起来看最保险。5. 推荐你配置两个快捷命令如果你经常需要项目 A → Java 8 项目 B → Java 17每次写export JAVA_HOME$(/usr/libexec/java_home -v 1.8)确实很烦。Mac 现在通常使用zsh可以编辑nano ~/.zshrc或者你用 VS Codecode ~/.zshrc添加alias java8export JAVA_HOME$(/usr/libexec/java_home -v 1.8); export PATH$JAVA_HOME/bin:$PATH alias java17export JAVA_HOME$(/usr/libexec/java_home -v 17); export PATH$JAVA_HOME/bin:$PATH保存之后source ~/.zshrc以后就非常简单了。切 Java 8java8检查java -version切 Java 17java17再java -version不过这个 alias 写法有个小问题如果你不停执行java8 java17 java8 java17每次export PATH$JAVA_HOME/bin:$PATH都会往 PATH 前面塞一个新的 JDK 路径。时间长了可能变成PATH zulu8/bin : temurin17/bin : zulu8/bin : temurin17/bin : ...虽然通常还能正常工作但不够干净。如果你只是偶尔切换问题不大。如果你经常做 Java 开发我更推荐下一种方案。6. 更专业的方式jenvjenv就是专门管理多个 Java 版本的。安装brew install jenv配置 zshecho export PATH$HOME/.jenv/bin:$PATH ~/.zshrc echo eval $(jenv init -) ~/.zshrc重新加载source ~/.zshrc然后把 JDK 添加进去。例如jenv add $(/usr/libexec/java_home -v 1.8)以及jenv add $(/usr/libexec/java_home -v 17)查看jenv versions可能类似1.8 1.8.0.XXX * 17 17.0.Xjenv最大的优势可以按照项目切换比如你的老项目~/projects/old-project要求 Java 8。进入cd ~/projects/old-project设置jenv local 1.8项目目录会出现.java-version内容类似1.8以后只要cd ~/projects/old-project就自动使用 Java 8。而另一个项目cd ~/projects/new-project jenv local 17就可以old-project/ ├── .java-version → 1.8 └── Java 8 new-project/ ├── .java-version → 17 └── Java 17这样比手动java8 java17更不容易忘。7.JAVA_HOME、PATH、java -version三者关系这三个非常容易混。可以这样理解JAVA_HOME │ │ 告诉 Maven / Gradle / Java 工具 │ “JDK 在哪里” │ ▼ /Library/Java/.../Contents/Home │ ├── bin/java ├── bin/javac ├── bin/jar └── ... PATH │ │ 告诉 Shell │ “输入 java 时去哪里找程序” │ ▼ $JAVA_HOME/bin java -version │ │ 真正执行 PATH 找到的 java │ ▼ 显示当前 Java 版本所以排查 Java 环境问题时我通常建议你一次执行echo $JAVA_HOME which java java -version javac -version如果这几个结果互相对不上就说明你的环境配置可能有冲突。8. 你的情况怎么选如果你现在只是因为项目需要某个老项目 → Zulu Java 8 某个新项目 → Temurin Java 17偶尔切一下那么先不用装jenv直接用export JAVA_HOME$(/usr/libexec/java_home -v 1.8) export PATH$JAVA_HOME/bin:$PATH和export JAVA_HOME$(/usr/libexec/java_home -v 17) export PATH$JAVA_HOME/bin:$PATH就足够了。如果你以后经常同时维护多个 Java 8 / 11 / 17 / 21 项目再用jenv管理会舒服很多。一句话记住JDK 是你安装的软件JAVA_HOME是“当前告诉其他程序去哪里找 JDK”PATH则决定你在终端输入java时实际执行哪个java。