JDK 21 是继 JDK 17 之后的又一个 LTS 长期支持版本从 2023 年 9 月正式发布到现在已经成了不少团队生产环境里的默认选择。我最近帮几个朋友处理过 JDK 21 的安装问题发现大家卡住的地方其实高度集中要么是下载源选错导致装了个来路不明的包要么是环境变量配完java -version还是报不是内部或外部命令要么是 Mac 上装完不知道 JAVA_HOME 到底该指向哪一层目录。这篇就把 Windows、macOS、Linux 三个平台从下载到环境变量配置的完整流程拆开讲清楚顺带把那些文档里不会写的坑一并交代了。不管你是刚接触 Java 的新手还是想从 JDK 8 升级到 21 的老手照着走一遍基本都能一次配通。1. 装之前先想清楚为什么是 JDK 21以及该选哪个发行版1.1 JDK 21 到底带来了什么值不值得升很多人装 JDK 21 是因为教程里说新版本好但具体好在哪说不清楚。我简单说几个实际开发中能直接感受到的点。JDK 21 引入了虚拟线程Virtual Threads的正式版本这是 Project Loom 的成果简单理解就是以前一个请求占一个操作系统线程线程池开个几百就顶天了现在可以用虚拟线程轻松撑起几十万的并发任务写起来还是同步代码的写法不用改成响应式那一套。另外还有分代 ZGC、记录模式Record Patterns、switch 的模式匹配等特性这些在写业务代码时能明显减少样板代码。从支持周期看JDK 21 是 LTS 版本官方支持到 2031 年左右这意味着你现在升级上去未来七八年不用再折腾大版本迁移。相比之下 JDK 17 虽然也是 LTS但虚拟线程这类关键特性没有如果你的项目涉及高并发 IO 场景21 的收益是很直接的。所以我的建议是新项目直接上 21老项目如果依赖库都兼容也值得规划升级。1.2 Oracle JDK、OpenJDK、各种发行版到底选哪个这是新手最容易懵的地方。市面上的 JDK 21 有好几个来源我列个表对比一下你按自己的场景选就行。发行版提供方授权适用场景我的建议Oracle JDKOracleNFTC 免费商用通用开发可用但注意授权条款Oracle OpenJDKOracleGPLv2CPE通用开发纯净适合学习Eclipse TemurinAdoptiumGPLv2CPE生产环境我个人最推荐Amazon CorrettoAmazonGPLv2CPE生产环境、云上AWS 用户首选Azul ZuluAzulGPLv2CPE生产环境支持周期长Microsoft Build of OpenJDK微软GPLv2CPEAzure、WindowsWindows 用户友好我自己的习惯是本地开发用 Eclipse Temurin因为它的安装包做得规范Windows 有 msi、macOS 有 pkg、Linux 有 deb/rpm环境变量基本自动配好省心。生产环境如果跑在云上就跟着云厂商推荐的发行版走比如 AWS 上就用 Corretto。这里要提醒一句别去那些乱七八糟的下载站下 JDK很多捆绑了广告软件甚至改了包内容一定要从官方或 Adoptium 这类可信源下载。提示判断一个 JDK 发行版是否靠谱看它是否公开源码、是否有明确的授权协议、是否有长期维护承诺。三者缺一谨慎使用。1.3 版本号里的门道21.0.1、21.0.2 该选哪个JDK 的版本号格式是主版本.次版本.安全版本比如 21.0.5。主版本 21 代表这是 JDK 21后面的 0.5 是补丁更新。原则很简单永远选当前最新的补丁版本。因为补丁版本只修 bug 和安全漏洞不引入新特性兼容性有保证。比如现在最新是 21.0.5那就下 21.0.5别去下 21.0.0 那个初始版。安全补丁对生产环境尤其重要很多漏洞就是靠这些补丁修的。2. Windows 平台从下载到环境变量一次配通2.1 下载安装包的正确姿势Windows 上我推荐直接下 msi 安装包而不是 zip 压缩包。原因很简单msi 会自动帮你配好 PATH 和 JAVA_HOMEzip 包解压完还得手动配新手很容易在这里翻车。去 Adoptium 官网adoptium.net找到 JDK 21 的下载区选 Windows x64 的 msi 包。如果你的机器是 ARM 架构比如某些 Surface就选 aarch64 版本。下载前确认一下系统架构右键此电脑→属性看系统类型那一栏。绝大多数人是 x64少数新设备是 ARM64。下错了架构装完运行会直接报错或者性能异常。文件大小大概 180MB 左右如果下下来只有几十 KB那多半是下到了网页而不是安装包重新点一次。2.2 安装过程中的关键选项双击 msi 后安装向导里有两个地方要注意。第一个是安装路径默认会装到C:\Program Files\Eclipse Adoptium\jdk-21.0.5.9-hotspot\这样的目录。我建议不要改路径就用默认的因为路径里带空格和特殊字符时某些老工具会解析出错。如果你非要改也请确保路径里没有中文和空格。第二个关键选项是安装向导里会问你要不要配置 JAVA_HOME 和 PATH还有要不要设置 JavaSoft 注册表项。这几个全部勾上。勾上之后安装程序会自动帮你把环境变量配好省掉后面手动配置的一大半工作。很多人装完发现环境变量没配就是因为这一步没勾。2.3 手动配置环境变量的完整步骤即使 msi 自动配了我也建议你手动检查一遍因为有时候自动配置会漏。步骤如下按Win R输入sysdm.cpl回车打开系统属性。点高级选项卡再点环境变量。在系统变量区域点新建变量名填JAVA_HOME变量值填你的 JDK 安装目录比如C:\Program Files\Eclipse Adoptium\jdk-21.0.5.9-hotspot。注意这里不要带\binJAVA_HOME 指向的是 JDK 根目录。找到系统变量里的Path双击编辑点新建添加%JAVA_HOME%\bin。把它移到列表靠前的位置避免被其他 Java 版本的路径抢先。一路点确定保存。这里有个高频错误有人把JAVA_HOME配成了C:\Program Files\Eclipse Adoptium\jdk-21.0.5.9-hotspot\bin多了个\bin。这样配完java命令能用但 Maven、Gradle 这些工具会找不到 JDK因为它们读 JAVA_HOME 后会自己拼\bin结果变成\bin\bin。记住JAVA_HOME 到根目录PATH 里才加 \bin。2.4 验证配置是否生效配完别急着关窗口先验证。关键点一定要重新开一个命令行窗口因为环境变量是启动时读取的老窗口读的还是旧值。新开一个 cmd 或 PowerShell依次执行java -version javac -version echo %JAVA_HOME%正常输出应该是类似openjdk version 21.0.5 2024-10-15这样的信息javac版本也要一致echo %JAVA_HOME%要输出你配的路径。如果java -version报不是内部或外部命令说明 PATH 没配好如果版本号是 1.8 或 17说明系统里有多个 JavaPATH 顺序不对把 JDK 21 的路径往前挪。注意Windows 上如果同时装了多个 JDKPATH 里谁在前谁生效。建议只保留一个 JDK 的 bin 在 PATH 里其他的删掉避免混乱。3. macOS 平台pkg 安装与 JAVA_HOME 的坑3.1 用 pkg 还是用包管理器macOS 上装 JDK 21 有两条路下 pkg 安装包或者用 Homebrew。我两种都用过说下区别。pkg 安装包的好处是图形化、一步到位装完系统会自动在/Library/Java/JavaVirtualMachines/下建好目录/usr/libexec/java_home也能识别到。Homebrew 的好处是升级方便brew upgrade一条命令搞定而且卸载干净。如果你只是本地开发我推荐 Homebrew命令是brew install --cask temurin21如果你不想装 Homebrew或者公司环境限制那就去 Adoptium 下 pkg 包双击安装一路下一步即可。两种方式装完JDK 都会出现在标准位置。3.2 macOS 上 JAVA_HOME 到底该指向哪这是 Mac 用户问得最多的问题。macOS 有个特殊工具叫java_home路径是/usr/libexec/java_home它能帮你找到当前系统里的 JDK。你可以这样用/usr/libexec/java_home -v 21它会输出 JDK 21 的实际路径比如/Library/Java/JavaVirtualMachines/temurin-21.jdk/Contents/Home。注意这个路径以 Contents/Home 结尾这才是 macOS 上 JDK 的根目录JAVA_HOME 要指向这里而不是.jdk那一层。配置环境变量时macOS 现在默认是 zsh所以编辑~/.zshrc老版本是 bash 就编辑~/.bash_profileexport JAVA_HOME$(/usr/libexec/java_home -v 21) export PATH$JAVA_HOME/bin:$PATH这样写的好处是以后你升级到 21.0.6路径变了也不用改配置java_home会自动找到最新的 21。如果你写死路径每次升级都得手动改很麻烦。3.3 让配置立即生效并验证改完~/.zshrc后执行source ~/.zshrc java -version echo $JAVA_HOME如果java -version还是老版本检查一下是不是有其他 JDK 的路径在 PATH 里更靠前或者~/.zshrc里有没有重复的 export。macOS 上还有个坑系统自带的/usr/bin/java是个 stub它会弹窗提示你装 Java如果你 PATH 里/usr/bin在前就会先命中这个 stub。解决办法就是把$JAVA_HOME/bin放到 PATH 最前面我上面的写法已经这么做了。4. Linux 平台apt、yum 与手动解压三种方式4.1 Ubuntu/Debian 用 apt 安装Ubuntu 上最省事的方式是用 apt但要注意默认源里的版本可能不是最新的 21。先更新索引sudo apt update sudo apt install -y temurin-21-jdk如果提示找不到包需要先加 Adoptium 的源。加源步骤稍微繁琐我一般直接用下面的方式下载 deb 包手动装。去 Adoptium 下temurin-21-jdk_21.0.5_amd64.deb然后sudo dpkg -i temurin-21-jdk_21.0.5_amd64.deb装完 JDK 会在/usr/lib/jvm/下比如/usr/lib/jvm/temurin-21-jdk-amd64。4.2 CentOS/RHEL 用 yum 或 rpmCentOS 系用 rpm 包sudo rpm -ivh temurin-21-jdk-21.0.5.x86_64.rpm或者用 yum 本地安装sudo yum localinstall -y temurin-21-jdk-21.0.5.x86_64.rpm装完同样在/usr/lib/jvm/下。这里提醒一句有些老系统自带的 yum 源里 JDK 版本很旧别用yum install java-21-openjdk这种除非你确认源里有 21。4.3 手动解压 tar.gz 的通用做法如果你没有 root 权限或者想装到自定义目录就用 tar.gz 包。这种方式最灵活也最通用任何 Linux 发行版都能用# 下载后解压到 /opt sudo tar -zxvf OpenJDK21U-jdk_x64_linux_hotspot_21.0.5_11.tar.gz -C /opt # 重命名方便管理 sudo mv /opt/jdk-21.0.511 /opt/jdk-21然后配置环境变量。Linux 上我推荐写到/etc/profile.d/jdk21.sh这样对所有用户生效sudo tee /etc/profile.d/jdk21.sh EOF export JAVA_HOME/opt/jdk-21 export PATH$JAVA_HOME/bin:$PATH EOF写完执行source /etc/profile.d/jdk21.sh生效。如果只想对当前用户生效就写到~/.bashrc里。4.4 Linux 环境变量配置失败的常见原因Linux 上配环境变量失败八成是这几个原因。第一source的文件不对比如你写到了/etc/profile但用的是 zshzsh 不读这个文件得写到/etc/zsh/zprofile或~/.zshrc。第二PATH 拼接时把$PATH写成了$PATH:后面没内容或者漏了$PATH导致系统命令全找不到。第三用sudo执行java时sudo 默认不继承用户环境变量得用sudo -E或者配sudoers里的env_keep。排查方法很简单执行echo $JAVA_HOME和echo $PATH看输出对不对再用which java看命中的是哪个 java。如果which java指向/usr/bin/java而不是你的 JDK说明 PATH 顺序有问题。5. 多版本共存与切换一台机器装多个 JDK 怎么办5.1 为什么需要多版本共存实际开发中经常遇到这种情况老项目还在 JDK 8 上跑新项目要用 21你不可能为了切项目就重装 JDK。所以多版本共存是刚需。核心思路是每个 JDK 装到独立目录环境变量通过切换 JAVA_HOME 来指向不同的版本。5.2 Windows 上的切换方案Windows 上我推荐用一个小脚本切换。建两个 bat 文件比如use-jdk8.bat和use-jdk21.bat内容分别是echo off setx JAVA_HOME C:\Program Files\Java\jdk1.8.0_381 setx PATH %JAVA_HOME%\bin;%PATH% echo Switched to JDK 8注意setx是永久设置改完要新开窗口才生效。更优雅的做法是用符号链接把C:\Java\current指向当前用的 JDKJAVA_HOME 永远指向C:\Java\current切换时只改链接指向。这样环境变量不用动切换更干净。5.3 macOS 和 Linux 上的切换方案macOS 上因为有了java_home工具切换特别方便。你可以在~/.zshrc里定义别名alias jdk8export JAVA_HOME$(/usr/libexec/java_home -v 1.8) alias jdk21export JAVA_HOME$(/usr/libexec/java_home -v 21)需要哪个版本就执行哪个别名。Linux 上可以用update-alternatives管理sudo update-alternatives --install /usr/bin/java java /opt/jdk-21/bin/java 2100 sudo update-alternatives --install /usr/bin/java java /opt/jdk-8/bin/java 800 sudo update-alternatives --config java最后一条命令会列出所有版本让你选选完java命令就指向对应版本。不过update-alternatives只管java命令JAVA_HOME 还得手动改所以更推荐用脚本切换 JAVA_HOME。6. 装完之后的验证与常见问题排查6.1 一套完整的验证清单装完 JDK 21 后别只看java -version就完事我建议跑一遍下面这套检查检查项命令预期结果Java 运行时版本java -version显示 21.x编译器版本javac -version显示 21.xJAVA_HOME 变量echo $JAVA_HOMEWin 用%JAVA_HOME%指向 JDK 根目录java 命令来源which javaWin 用where java指向 JDK 的 bin编译运行测试写个 Hello.java 编译运行正常输出最后那个编译运行测试最实在能一次性验证 java 和 javac 都配对了。写个最简单的public class Hello { public static void main(String[] args) { System.out.println(JDK System.getProperty(java.version)); } }javac Hello.java编译java Hello运行输出JDK 21.0.5就说明全通了。6.2 高频问题速查表我把这些年遇到的和网上问得最多的问题整理成表方便你对号入座。问题现象根本原因解决办法java不是内部或外部命令PATH 没配或没生效检查 PATH 含%JAVA_HOME%\bin重开窗口java -version显示旧版本多个 JDKPATH 顺序错把目标 JDK 的 bin 移到 PATH 最前Maven 报找不到 JDKJAVA_HOME 配到了 bin 目录JAVA_HOME 改为 JDK 根目录javac能用但java不行只配了部分路径确认 bin 目录完整加入 PATHMac 上java弹窗提示安装命中了系统 stub把$JAVA_HOME/bin放 PATH 最前Linux sudo 下找不到 javasudo 不继承环境变量用sudo -E或配 sudoers环境变量改了不生效没 source 或没重开窗口source 配置文件或新开终端编译报不支持发行版本 21IDE 或构建工具没设对检查 IDE 的 SDK 和编译级别设置6.3 几个容易被忽略的细节第一个细节是 IDE 的配置。你系统环境变量配好了但 IntelliJ IDEA 或 Eclipse 里可能还指向老 JDK。IDEA 里要去File → Project Structure → SDK里把项目 SDK 改成 21同时Project language level也要设成 21。Eclipse 里在Preferences → Java → Installed JREs里添加 JDK 21。第二个细节是构建工具的配置。Maven 的pom.xml里要设maven.compiler.source21/maven.compiler.source和maven.compiler.target21/maven.compiler.target或者用release21/release。Gradle 里要设sourceCompatibility JavaVersion.VERSION_21。这些不设编译时还是会按老版本处理可能报错。第三个细节是某些第三方库的兼容性。比如你搜热词里提到的 aspose-words这类库对 JDK 版本有要求升级 JDK 21 前要确认你用的版本支持 21否则运行时会报UnsupportedClassVersionError。一般库的官方文档或 release notes 里会写明支持的 JDK 范围升级前查一下能省很多事。提示升级 JDK 大版本前先在测试环境跑一遍完整的构建和测试确认所有依赖库都兼容再动生产环境。7. 我踩过的坑和几条实在建议说几个我自己真实踩过的坑。有一次在 Windows 上配完环境变量java -version死活显示 1.8查了半天发现是之前装 Oracle 时在 PATH 里留了个C:\ProgramData\Oracle\Java\javapath这个路径排在前面里面是 Oracle 的 java.exe 快捷方式。解决办法就是把这个路径从 PATH 里删掉或者把 JDK 21 的路径挪到它前面。这种隐藏的 Java 路径特别坑因为你在环境变量界面里不一定一眼看到。还有一次在 Linux 服务器上用sudo跑脚本时 java 找不到排查发现是 sudo 默认重置了环境变量。后来在/etc/sudoers里加了Defaults env_keep JAVA_HOME PATH才解决。如果你经常用 sudo 跑 Java 相关命令这个配置值得加上。最后给几条实在建议。第一下载 JDK 只从官方或 Adoptium、Corretto 这类可信源别图快用第三方下载站。第二环境变量配完一定要新开窗口验证别在老窗口里反复试。第三多版本共存时用脚本或符号链接切换别每次手动改环境变量容易改乱。第四升级大版本前先查依赖库兼容性尤其是那些用了字节码增强或反射的库。第五把 JDK 的安装路径和版本记在笔记里过几个月你自己都忘了装在哪、装的哪个小版本。这套流程我在 Windows 11、macOS Sonoma、Ubuntu 22.04 上都实测过按上面的步骤走基本不会出问题。真遇到卡住的地方先看echo $JAVA_HOME和which java这两个输出八成问题都能定位到。
企业数字化 ERP 产品动态
相关推荐
Substrate区块链开发框架实战:用Rust构建自定义链的核心设计 1. 项目概述:别被名字骗了,Substrate 到底是个什么我第一次听到 "Substrate" 这个词,是在一个技术社群的闲聊里。有人问“你想用 Rust 写区块链,选哪个框架”,底下回答里高频出现 Substrate。我当时的第一反… · 2026/9/26 16:02:44
DSec沙箱平台解析:如何支撑300万个Agent环境隔离运行 1. 从“300万个Agent环境”说起:DSec到底在解决什么问题第一次看到“DSec可支持300万个Agent环境”这个说法,我脑子里冒出来的第一个念头不是“哇好厉害”,而是“这得烧多少钱”。做过Agent开发的人都知道,跑一个Agent环境不难&am… · 2026/9/26 16:02:44
Python 编码实战:Unicode 与 UTF-8 的关系,从报错到配置文件一次讲清 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 16:02:44
蜜罐搭建实战指南 蜜罐是什么和搭建步骤教程
一、蜜罐是什么
蜜罐(Honeypot)是一种网络安全工具,用于诱捕攻击者,通过模拟易受攻击的系统或服务来收集攻击信息。蜜罐可以用于研究攻击行为、检测潜在威胁、提高安全防护能力等。
蜜罐的主要功能
… · 2026/9/26 16:33:42
Wan2.2二次元文生视频实战:ComfyUI整合包避坑与参数优化 简介:面向ComfyUI使用者的二次元文生视频基础工作流资源,适配Wan2.2与RapidAIOMega推理流程,既适合刚接触节点式文生视频、希望直接获得可运行模板的创作者,也适合需要在项目里快速嵌入文生视频能力的开发者参考。压缩包内共有1个… · 2026/9/26 16:33:35
工业以太网温湿度传感器:Modbus TCP与MQTT选型及部署实战 1. 从一根模拟线到一根网线:工业监控布线的现实困境如果你在工厂做过设备维护或者产线改造,大概率见过这样的场景:车间角落里一台温湿度变送器,拉着一根四芯屏蔽线,穿过桥架、绕过变频器、贴着伺服驱动器,最… · 2026/9/26 16:33:17
齿轮加工在机测量实战:齿坯找正与齿面余量检测全解析 1. 齿轮在机测量到底在解决什么问题干了十几年齿轮工艺,我越来越觉得,在机测量这四个字,是区分“能把齿轮做出来”和“能把齿轮做稳、做精、做便宜”的一道分水岭。很多人第一次听到“齿轮加工在机测量”,脑子里浮现的是三坐标测量… · 2026/9/26 16:33:17
协作机器人接口防护:ESD与浪涌的系统级解决方案 1. 协作机器人现场最“沉默”的杀手:不是碰撞,而是看不见的电涌我第一次在汽车焊装车间看到协作机器人手臂突然停摆,是在一个雷雨天的下午。产线没断电,PLC没报错,示教器界面一切正常,但机械臂就是不响应任… · 2026/9/26 16:33:10
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍 简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践 一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46