ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

JDK卸载安装与环境变量配置:残留清理、多版本切换全攻略

JDK卸载安装与环境变量配置:残留清理、多版本切换全攻略 如果你经历过“卸载了 JDK环境变量还指向旧版本”这种鬼打墙现象那你应该明白JDK 的卸载与安装里真正难的往往不是下载安装包而是把旧环境彻底清干净。很多同事找我排查 Java 环境问题十次里有八次不是代码问题是 JDK 装得乱、卸得不干净、Path 路径顺序不对。这篇内容我按 Windows、Linux、macOS 三个平台拆开讲从卸载清单、安装步骤、环境变量配置到多版本切换和 IDEA 中指定 JDK全部过一遍。适合刚接触 Java 的新手也适合那些准备从老 JDK 升级、或者被“JDK 环境变量配置失败”折腾到头疼的老开发。1. 为什么卸载比安装还要小心1.1 卸载不干净到底会出什么问题JDK 不是简单复制一个文件夹就能算安装完成的东西。它在安装阶段会往系统里写入环境变量、注册表信息、快捷方式、公共 JRE 入口甚至还有安全策略和启动器文件。卸载的时候如果只删掉主目录这些残留信息还会留在系统里继续影响后续新版本的安装和使用。最常见的情况就是你明明从控制面板里卸载了 JDK 8结果新装了 JDK 17打开命令行执行java -version显示的却还是 1.8。这就是因为 Windows 下C:\Program Files\Common Files\Oracle\Java\javapath这个公共路径里还有旧的java.exe而这个路径在 Path 变量里的顺序比新安装的路径更靠前系统优先找到了它。残留的注册表项还会干扰下一次安装。有些安装程序在检测到旧版本残留时会报错提示“另一个 Java 安装正在运行”或者“无法写入注册表”这时候不是安装包有问题而是系统里还留着旧 JDK 的痕迹。1.2 动手之前先把现场摸清楚在没有确认当前环境之前不要直接开删。我建议先做一次现场检查把当前 Java 安装的位置、版本、环境变量内容记录下来。这样做有两个好处一是卸载完对比时可以确认是否清干净二是如果机器上有老项目依赖特定版本你还能知道现在到底跑的是什么 JDK。Windows 上执行where java where javac echo %JAVA_HOME% java -versionLinux 和 macOS 上执行which java which javac echo $JAVA_HOME java -versionwhere或which输出的是实际生效的java.exe或java文件路径。echo看的是 JAVA_HOME 变量值。这里有一个非常重要的判断点如果java -version显示的版本和你设置的 JAVA_HOME 不一致说明 Path 里存在环境变量以外的 Java 入口这种机器卸载起来最容易出现“漏网之鱼”。我还会多看一眼安装目录里有哪些文件。完整 JDK 应该会有bin、lib、conf、include这些目录。如果某个目录里只有jre那通常是老版本的独立 JRE而不是完整 JDK。2. 三种操作系统下的 JDK 卸载实操2.1 Windows控制面板卸载只是第一步Windows 下卸载 JDK第一步是用官方途径卸载程序。打开“设置 - 应用”找到对应版本的 Java 或 JDK点击卸载。有些 Oracle JDK 安装包会带单独的卸载程序也可以用控制面板里的“程序和功能”处理。这一步之后不能马上认为卸载完成。接下来要检查并删除残留目录常见路径包括C:\Program Files\Java\jdk-versionC:\Program Files\Java\jre-versionC:\Program Files\Common Files\Oracle\Java\javapathC:\Users\用户名\AppData\LocalLow\Oracle\JavaC:\ProgramData\Oracle\Java我见过不少人删完主目录后没有处理javapath导致新 JDK 一直无法生效。如果你发现这个目录还在最好把里面的java.exe、javaw.exe、javaws.exe一并清掉或者直接把整个Oracle\Java\javapath目录从系统里移除。注册表清理要谨慎不推荐用什么“一键清理工具”把 Java 相关键值全部乱删。你只需要检查HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft和HKEY_CURRENT_USER\SOFTWARE\JavaSoft找到对应版本残留键值手动删除。如果你不想碰注册表至少要把当前用户和系统变量里的 JAVA_HOME、CLASSPATH以及 Path 中所有指向旧 JDK 的条目删掉。注意删除注册表项之前先备份对应键值。清理注册表不是越多越好宁可少删不能误删其他软件依赖的项。2.2 Linux区分系统包和手工解压安装Linux 下的 JDK 来源不同卸载方式也不同。如果当初是用apt、yum、dnf这类包管理器安装的那就用对应的包管理命令卸载不要手动去删目录否则包管理器的数据库里还会有记录之后升级系统时可能重新装回去。Debian/Ubuntu 系统执行sudo apt remove openjdk-17-jdk sudo apt autoremove如果想要彻底清理配置文件可以用sudo apt purge openjdk-17-jdk。Red Hat/CentOS 系则用sudo yum remove java-17-openjdk如果是手工下载 tar.gz 解压安装的那就简单很多直接删除解压目录即可sudo rm -rf /usr/local/java/jdk-17但目录删完之后软链接和 alternatives 也要处理。Linux 上很多环境是用update-alternatives管理的残留的软链接会导致java -version仍然指向旧文件。处理方式sudo update-alternatives --list java sudo update-alternatives --remove java /usr/local/java/jdk-17/bin/java同时检查/etc/profile.d/下是否有自定义的 JDK 环境变量脚本比如jdk17.sh、java.sh之类的文件确认没用了就删掉。这些脚本一旦残留会影响后面新 JDK 的环境配置。2.3 macOS删目录之外还要清理插件和缓存macOS 上的 JDK 通常安装在/Library/Java/JavaVirtualMachines/。安装的 JDK 版本会以.jdk目录形式存在比如/Library/Java/JavaVirtualMachines/jdk-17.jdk删除操作很简单sudo rm -rf /Library/Java/JavaVirtualMachines/jdk-17.jdk但 macOS 上还有一个最容易忽略的部分是系统 Java 插件目录和偏好设置残留。老版本 JDK 安装包往往还会写入/Library/Internet Plug-Ins/JavaAppletPlugin.plugin和/Library/PreferencePanes/JavaControlPanel.prefpane这些是 JRE 和 Java 控制面板相关的内容卸载 JDK 后如果还残留执行java -version时仍可能被系统调用。干净的做法是把这些也一起删掉sudo rm -rf /Library/Internet Plug-Ins/JavaAppletPlugin.plugin sudo rm -rf /Library/PreferencePanes/JavaControlPanel.prefpane sudo rm -rf ~/Library/Application Support/Oracle/Javac 还要清掉 Java 的缓存记录。执行下面的命令让系统重新生成 Java 环境信息sudo /usr/libexec/java_home -v 17 /usr/libexec/java_home -V如果第二个命令列出的版本里还有你不想要的条目说明旧 Java 信息没有清干净可以检查/Library/Java/JavaVirtualMachines目录里是不是真的已经空了。3. 重新安装版本选择、下载渠道与安装细节3.1 版本怎么选别只看“最新”JDK 版本选择是卸载之后最容易纠结的问题。很多新手喜欢装官网最新版但实际开发中新版本不一定合适尤其是老项目对编译器和运行时的兼容性要求很敏感。版本是否 LTS使用场景JDK 8LTS老项目、Spring Boot 2、Android 构建工具链JDK 11LTS过渡期企业项目、部分云平台默认环境JDK 17LTS目前最主流的稳定版本Spring Boot 3 和主流框架默认支持JDK 21LTS新项目、需要较新语言特性或虚拟线程等功能的场景JDK 1.6 / 1.7已停止支持老软件强制依赖环境不建议用于新项目如果你的项目还跑在 Spring Boot 2 或更老的框架上那大概率还是用 JDK 8。如果项目已经升级到 Spring Boot 3则至少需要 JDK 17。对于大部分新业务系统我个人的建议是直接上 JDK 17因为它是当前兼容性和生态支持都比较平衡的版本各大中间件、IDE、云平台都对它做了充分适配。“JDK 降级到 17”这种需求也很常见。很多人装了 JDK 21 甚至更高版本启动老项目时报错比如 Maven 编译失败、某个依赖反射调用异常。降级最简单的方式不是卸载高版本而是先装一个 JDK 17然后把 JAVA_HOME、Path 都指到 17再把高版本从全局环境里移除或者保留高版本但不在全局 Path 中配置。3.2 下载渠道那么多怎么判断靠谱JDK 下载的渠道很杂搜索引擎一搜能出来一堆所谓的“官网下载”“网盘分享”。我的原则是优先去正式发行方站点其次是可信任的开源镜像最后才是第三方分享。Oracle JDK可以在 Oracle 官网的 Java Downloads 页面下载历史版本需要去 Java Archive 页面找。Eclipse TemurinAdoptium面向 OpenJDK 的免费发行版更新及时也是我目前用得最多的版本。Azul Zulu另一个很成熟的开源发行版社区活跃。国内开源镜像站部分高校和企业提供的 JDK 镜像优点是下载速度快。这类镜像站在业界口碑良好但一定要确认是官方公开发布的文件不能随便用别人二次封装的安装包。不管是哪个渠道下载完成后最好校验一下文件的哈希值。Windows 下可以用certutil -hashfile jdk-17_windows-x64_bin.zip SHA256Linux 和 macOS 下用sha256sum jdk-17_linux-x64_bin.tar.gz校验值和官方公布的一致才说明文件完整且没有被替换过。现在很多安装失败看起来是环境问题实际是安装包损坏或被人为改动过这一点很关键。3.3 Windows / Linux / macOS 的安装步骤Windows 下我一般推荐下载.msi或.zip包。.exe安装向导会引导你设置安装路径但要注意把安装目录选在简单路径下比如C:\java\jdk-17或D:\dev\jdk-17不要放在带空格或中文的目录里否则后面写脚本、配置环境变量很容易出问题。如果你用的是.zip包直接解压到目标目录就行本质上是绿色版但手动配置环境变量是必需的。Linux 下常见两种方式。想要省事直接用包管理器sudo apt install openjdk-17-jdk想要版本更可控、目录更清楚就手工解压sudo mkdir -p /usr/local/java sudo tar -xzf jdk-17_linux-x64_bin.tar.gz -C /usr/local/java解压完成后需要把 Java 注册到 alternatives 里或者直接写环境变量脚本后面环境变量部分我会详细讲。macOS 下最省心的方式是双击.dmg或.pkg安装包。安装完后 JDK 会自动出现在/Library/Java/JavaVirtualMachines/。如果你下载的是.tar.gz手工安装也可以sudo mkdir -p /Library/Java/JavaVirtualMachines/jdk-17.jdk sudo tar -xzf jdk-17_macos-x64_bin.tar.gz -C /Library/Java/JavaVirtualMachines/jdk-17.jdk注意 macOS 下手工放置 JDK 时需要把目录结构层级放对Contents/Home应该在.jdk目录内部否则/usr/libexec/java_home无法识别这个 JDK。不管哪个平台安装完成后我习惯先看一眼目录内容确认存在bin/javac而不是只有bin/java。只装了 JRE 或装了残缺 JDK 包后面编译代码时才会发现javac找不到。4. 环境变量配置JDK 安装后最容易翻车的环节4.1 JAVA_HOME、PATH、CLASSPATH 到底分别管什么很多配置失败是因为不清楚这几个变量的分工。简单来说JAVA_HOME告诉系统你的 JDK 安装在哪里注意是 JDK 的根目录不是bin目录。Maven、Gradle、Tomcat 这类工具都会读取这个变量。PATH是系统搜索可执行文件的路径列表。只有把%JAVA_HOME%\bin或$JAVA_HOME/bin加进 PATH命令行才能直接执行java和javac。CLASSPATHJava 编译和运行时的类搜索路径。以前老教程喜欢设置成.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar但在 JDK 9 之后模块系统和默认类路径机制已经改变了普通项目基本不需要再手工设置 CLASSPATH。乱设反而会踩坑比如把路径写错导致某些类找不到。我见过很多同事把 JAVA_HOME 指向了C:\Program Files\Java\jdk-17\bin结果 Maven 启动时报JAVA_HOME is not defined correctly。这个问题就是没理解 JAVA_HOME 应该指向 JDK 根目录而不是 bin 目录。4.2 Windows 环境变量配置与常见失败Windows 下配置环境变量我建议走图形界面不要用setx命令直接修改系统 Path。setx会把 Path 变量截断尤其是系统 Path 原本超过一定长度时用命令设置很容易把原有内容吞掉导致其他命令也一起失效。正确步骤打开“系统属性 - 高级 - 环境变量”。在系统变量里新建JAVA_HOME值填 JDK 根目录比如C:\java\jdk-17。找到 Path 变量编辑并点击“新建”添加%JAVA_HOME%\bin。确认 Path 中不存在其他旧 JDK 路径特别是C:\Program Files\Common Files\Oracle\Java\javapath。重新开启一个新的命令行窗口不要用旧窗口。如果你需要临时切换不同版本的 JDK也可以在命令行里临时指定set JAVA_HOMED:\dev\jdk-17 set PATH%JAVA_HOME%\bin;%PATH%这个方式只在当前窗口生效不会污染全局环境适合做临时测试。Windows 下最常见的失败场景是JAVA_HOME 配置完成echo %JAVA_HOME%也能输出正确路径但java -version还是旧版本。这时候执行where java大概率能看到两个路径其中一个来自javapath公共目录。解决方法是把 Path 里优先级更高的旧入口移除或者把新 JDK 的bin路径移动到 Path 列表更靠前的位置。还有一个很多人忽略的问题如果你同时在用户变量和系统变量里配置了 JAVA_HOME不同工具的读取规则可能不同。我建议统一只配置系统变量避免用户变量和系统变量互相干扰。4.3 Linux 和 macOS 的配置方式Linux 下如果你是用包管理器安装的 JDK安装脚本一般会帮你配置好一部分环境但手工解压的 JDK 必须自己写环境变量。我习惯在/etc/profile.d/下新建一个独立的脚本文件比如jdk17.sh内容如下export JAVA_HOME/usr/local/java/jdk-17 export PATH$JAVA_HOME/bin:$PATH保存后执行source /etc/profile当前用户临时切换可以用~/.bashrc或~/.zshrc但全局环境建议放/etc/profile.d这样新登录的用户也能读到。macOS 推荐用系统自带的java_home工具来设置export JAVA_HOME$(/usr/libexec/java_home -v 17) export PATH$JAVA_HOME/bin:$PATH这样做的好处是不会写死 JDK 路径以后如果系统上有多个版本可以通过java_home自动定位。如果你用的是 zsh把这两行加到~/.zshrc里如果还在用 bash就加到~/.bash_profile。macOS 配置完成后同样要开新终端验证。如果java -version没变先执行/usr/libexec/java_home -V看看系统到底识别到哪些 JDK是不是把路径放在了/Library/Java/JavaVirtualMachines下。很多人直接解压到用户目录系统识别不到自然就不生效。5. 多版本共存、降级到 JDK 17 与 IDEA 配置5.1 一台机器多个 JDK怎么切换才不混乱很多人以为一台机器只能装一个 JDK其实不是。我经常在一台机器上同时保留 JDK 8 和 JDK 17做不同项目时切换着用。Windows 下我不建议频繁修改全局 JAVA_HOME因为系统里其他程序可能正依赖某个版本。更稳妥的做法是在 IDEA 里给每个项目单独指定 JDK或者在命令行里用临时环境变量切换。Linux 下可以用update-alternatives维护多个版本sudo update-alternatives --config java sudo update-alternatives --config javac选择对应的数字序号就能切换默认版本JDK 目录之间互不干扰。macOS 下切换比较优雅直接动态获取export JAVA_HOME$(/usr/libexec/java_home -v 17)把这里的版本号改成 JDK 8export JAVA_HOME$(/usr/libexec/java_home -v 1.8)如果你需要经常切换可以在~/.zshrc里写几个别名比如usejdk8、usejdk17每次执行别名就能切到目标版本不用记命令。5.2 IDEA 中指定 JDK 的正确姿势IDEA 里配置 JDK很多新手爱直接改系统环境变量其实在 IDEA 中单独指定项目 SDK 反而更清晰。打开File - Project Structure - Project在Project SDK这里点击Add SDK - JDK选择你安装好的 JDK 根目录即可。你需要对每个项目都做一次这个操作因为项目使用的 JDK 版本和 IDE 自身运行的 JDK 版本是两个独立概念。如果需要为项目配置语言级别也是在同一个界面里调整比如项目用的是 JDK 17但某个子模块想用 JDK 8 的语法级别这在 Project Structure 里都能单独设置。还有一个容易踩坑的地方是 Maven 或 Gradle 的编译环境。即使 IDEA 项目 SDK 选的是 JDK 17Maven 构建时也可能读的是系统 JAVA_HOME 或 IDE 内置的 JBR。你在 IDEA 的Settings - Build Tools - Maven - Runner里可以看到 JRE 的设置强制指定成项目所用的 JDK 即可。Gradle 则可以通过org.gradle.java.home参数指定 JDK 路径。5.3 JDK 17 下常见库的版本选择升级到新 JDK 后旧的第三方库可能因为模块系统、权限收紧或字节码版本问题而报错。JDK 17 比 JDK 8 严格很多很多类库如果不更新版本反射调用时会直接抛InaccessibleObjectException之类的错误。比如 Bouncy Castle 加密库JDK 17 下选择依赖时优先使用后缀为jdk18on的版本例如bcprov-jdk18on。这是因为新后缀系列适配了 JDK 9 以来的模块化架构和类路径规则老的jdk15on系列在 JDK 17 下虽然有些还能用但新功能维护已经逐渐迁移到新系列了。Lombok 也要注意版本老版本在 JDK 17 上会报编译错误最好升到 1.18.30 以上。Spring Boot 项目则要看大版本Spring Boot 2.x 可以跑在 JDK 8 到 17 之间但 Spring Boot 3 强制要求 JDK 17 起步。不是项目一升级到 JDK 17 就万事大吉之前嵌入的字节码增强、APM Agent、字节码工具都得同步看看兼容性。6. 常见问题速查与避坑实录6.1 问题排查表按症状查原因症状大概率原因处理方法java -version还是旧版本Path 中存在其他 java 入口或 javapath 残留执行where java清理旧入口javac提示找不到命令PATH 中没有 JDK 的 bin 目录把%JAVA_HOME%\bin加入 Path重新卸载安装后无法安装注册表残留或文件权限冲突清理 JavaSoft 残留键值以管理员身份运行安装包JAVA_HOME 设置后 Maven 报错变量指向了 bin 目录修改为 JDK 根目录并重新开终端命令行里 echo 正常但工具读取失败系统变量和用户变量冲突统一只配置系统变量老项目报 UnsupportedClassVersionError编译和运行 JDK 版本不一致编译版本使用-source、-target或降级到项目要求的 JDKIDEA 项目正常命令行编译版本不对IDEA 项目 SDK 和系统 JAVA_HOME 不一致检查 IDEA 的 Project SDK、Maven Runner JRE 设置macOS 装完 JDK 后系统识别不到目录层级不对或路径不在标准目录下将 .jdk 放到/Library/Java/JavaVirtualMachines/排查这类问题要记住一个原则先看实际执行的程序路径再看环境变量最后看缓存和注册表。很多人一上来就改环境变量但方向错了越改越乱。6.2 我踩过的坑和现在的习惯我自己早期也犯过一个很低级的错误。当时为了给项目降级到 JDK 17直接把旧的高版本 JDK 目录删了结果 Path 里还留着旧路径命令行执行java -version一直提示找不到命令。后来才明白卸载之后必须重新检查 Path 和 JAVA_HOME不能只依赖安装包的自动处理。现在我的习惯是系统全局只保留一个主用 JDK 版本项目需要其他版本时通过 IDEA 的项目 SDK 或工具链配置来解决。遇到多个 JDK 共存的机器我不轻易动全局环境变量而是先写一个临时脚本确认当前使用的是哪个版本再决定切换方式。还有一个很实用的习惯是每次重装后绝不只看java -version一个命令我会同时跑java -version和javac -version。这两个命令的输出都比较直观一眼能看出编译环境和运行环境是不是一致。再执行一次where java或which java确认调用的路径确实是我刚安装的那个 JDK。整个过程加起来不到一分钟但可以省掉之后非常多的排查时间。
返回列表