要完整掌握系统已安装的Java版本,需结合注册表(Windows)、/usr/libexec/java_home(macOS)或包管理器+路径扫描(Linux),并注意JAVA_HOME与PATH对不同工具的影响。

直接运行 java -version 只能查到当前 PATH 中生效的 Java 版本,无法反映系统真实安装情况。要完整掌握已安装版本,必须结合系统路径扫描与注册表(Windows)或包管理器(Linux/macOS)信息。
Windows 上查全所有已安装 JDK/JRE
Windows 的 Java 安装常分散在不同位置,且注册表残留多。仅靠 java -version 或环境变量容易漏掉旧版本或仅 JRE 的安装。
- 检查注册表键
HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\JDK和HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\JRE,每个子键名通常是版本号(如1.8.0_381),对应值含JavaHome - 手动扫描常见路径:
C:\Program Files\Java\、C:\Program Files (x86)\Java\,看是否存在jdk-xx或jre1.8.0_xx等目录 - 注意:部分 JDK 安装(如 Adoptium/Amazon Corretto)不写入 JavaSoft 注册表,而是用
HKEY_LOCAL_MACHINE\SOFTWARE\Eclipse Foundation\或厂商专属路径,需额外排查
macOS 用 /usr/libexec/java_home 查系统级 JDK
macOS 不依赖 PATH 查找 JDK,而是由 /usr/libexec/java_home 统一管理所有通过官方或 Homebrew 安装的 JDK。这是最可靠的方式。
- 列出全部已注册 JDK:
/usr/libexec/java_home -V
- 获取指定版本路径,例如 JDK 17:
/usr/libexec/java_home -v 17
- 注意:
java -version显示的版本可能来自/usr/bin/java(系统默认软链),它不一定等于java_home -V列出的最新版;macOS 会按策略选一个作为默认,但所有注册版本都可手动切换
Linux(Debian/Ubuntu/CentOS/RHEL)依赖包管理器 + 手动路径扫描
Linux 发行版差异大,OpenJDK 多通过 apt/yum/dnf 安装,但用户也可能手动解压 tar.gz 到任意路径,因此必须两者结合。
立即学习“Java免费学习笔记(深入)”;
- 查已安装包:
apt list --installed | grep openjdk
(Debian/Ubuntu)或dnf list installed | grep java
(RHEL/Fedora) - 查所有
java可执行文件位置:update-alternatives --list java
(Debian/Ubuntu)或alternatives --list | grep java
(RHEL/CentOS) - 手动扫描:
/usr/lib/jvm/是 OpenJDK 默认安装根目录;/opt/java/、/home/$USER/sdk/等也常见于手动安装 - 注意:
which java和readlink -f $(which java)只能定位当前 shell 使用的二进制,不能代表“已安装”——比如卸载了 JDK 但未清理/usr/bin/java软链,结果会误导
Java 版本切换实际生效的关键点
改环境变量只是第一步,真正影响 java、javac、mvn 等工具行为的,是它们各自对 JAVA_HOME 和 PATH 的解析逻辑。
-
java和javac本身不读JAVA_HOME,只认 PATH;但很多工具(Maven、Gradle、IDEA)会优先读JAVA_HOME,再 fallback 到 PATH - Shell 启动新终端后,
JAVA_HOME不自动继承——需在~/.zshrc或~/.bashrc中显式 export,并source生效 - GUI 应用(如 IntelliJ)通常不继承终端环境变量,需在 IDE 设置中单独指定 SDK,或通过系统级方式(如 macOS 的
launchctl setenv JAVA_HOME)注入
版本管理真正的难点不在“查得到”,而在“切得准”:PATH、JAVA_HOME、工具自身缓存、GUI 进程继承机制,四者稍有不一致就会出现 java -version 和 mvn -v 输出不同版本的情况。动手前先确认你要控制的是哪个环节。










