简介:面向 Windows 64 位平台的 JDK 23 二进制压缩包,适合需要在 Windows 环境下搭建 Java 开发环境、运行与调试 Java 程序的开发者使用。JDK 23 是 Java 工具链的重要版本更新,包内提供编译器、虚拟机、运行时环境及配套命令,可支撑从源代码编译、打包到部署运行的全流程;bin、lib、conf 等目录结构也便于开发者按需定位工具与配置。压缩包共 425 个文件、约 228.77MB,包含 dll 动态链接库、jmod 模块文件、license 与 copyright 许可文档、exe 可执行程序及 md 说明文档等,文件类型覆盖 Java 运行库、模块化体系与授权信息等关键组成部分。目前已有 240 人学习下载,压缩包解压后可直接用于本地 JDK 安装,也能作为搭建 IDE 开发环境、配置 Java 环境变量时的核心安装包;对于需要快速获得官方版本 JDK 的开发者而言,这一压缩包省去在线安装的等待,便于离线部署、企业内网分发与版本归档,适合从入门到进阶的开发者反复使用。
1. 手拿 jdk-23-windows-x64-bin.zip,先搞清楚这包东西能干嘛
拿到jdk-23-windows-x64-bin.zip这个文件名,很多人的第一反应是“不就是个解压版 JDK 吗”,但真正动手才发现,从解压到跑通第一个java -version,中间的踩坑点比想象中多。这个压缩包代表的是 JDK 在 Windows 平台上最干净的一种存在形式:没有安装向导、不写注册表、不装后台更新服务,解压出来的目录本身就是一套完整工具链。对需要手动控制 Java 环境的开发者,或者要给测试环境、容器基础镜像做部署基线的人来说,它比双击执行的 exe 安装版更可控,也更方便用脚本复现。
这篇文章就从这份 zip 展开,按“这是什么 → 怎么装 → 怎么验证 → 坑在哪 → 怎么进阶用”的顺序,把整个链路讲透。内容不依赖任何 IDE 或构建工具,纯命令行就能跟完,适合刚入门的 Java 新人也适合被环境问题反复折腾的熟手。
2. 为什么我推荐 bin.zip 而不是 exe 安装版:两个关键区别
2.1 压缩包和安装器在 Windows 上的本质区别
JDK 在 Windows 上常见的分发方式有两种:一种是jdk-23-windows-x64-bin.zip这样的纯压缩包,另一种是同名 exe 安装版。很多人误以为它们只是打包格式不同,实际上差别很大。
exe 安装版走的是 Windows Installer 流程,它会做几件 zip 版不做的事:写入注册表、创建开始菜单快捷方式、配置系统级环境变量(通常还会装一个后台更新服务)。这些动作对单机用户是省事的,但放到批量部署、容器化或者多 JDK 版本并存的场景里就成了干扰项。举例来说,安装版默认可能把 JDK 装到C:\Program Files\Java\这种带空格的路径下,某些老旧的构建脚本或者内网部署工具遇到空格路径会直接翻车;而 zip 版可以放在C:\java\jdk-23这种短路径下,路径可控性高出一个量级。
我一般会按这个逻辑选:如果是给个人开发机装一套“长期用”的 JDK,exe 安装版体验确实好;如果是做测试环境准备、准备集成到自动化脚本里,或者要同时维护多个 JDK 版本(比如项目 A 用 21、项目 B 用 23),那就必须用 zip 版。zip 版的另一个优势是“无痕迹卸载”——直接把目录删掉,再清理一下环境变量就完事,不会在注册表里留下残骸。这一点在做临时环境时非常实用。
还要注意一个背景:JDK 的版本节奏是每六个月出一个功能版本,像 23 这种版本号并不属于长期支持版本。企业生产环境通常更青睐 LTS 版本,但如果你只是想尝鲜新语法、跑一下新库,或者项目明确要求功能版本的特性,那这个 zip 包照样能用。只要把 JRE 层面的兼容性测一遍,开发和测试环境用它没有任何问题。
2.2 校验下载文件:这一步省掉,后面全是玄学
下载任何公开发布的软件包,校验文件完整性都不该跳过,尤其是 JDK 这类工具链,一旦文件损坏或被人掉包,后续编译和运行报的错误会非常难查。我见过有人从非官方渠道下了个“优化版 JDK”,结果编译时总是报奇怪的编码错误,折腾了两天才发现是文件本身有问题。
拿到jdk-23-windows-x64-bin.zip之后,第一件事不是解压,而是算哈希值。Windows 自带的 PowerShell 和certutil都能做,命令如下:
# PowerShell 方式,输出 SHA256 哈希 Get-FileHash .\jdk-23-windows-x64-bin.zip -Algorithm SHA256# 传统 cmd 方式,certutil 同样可用 certutil -hashfile jdk-23-windows-x64-bin.zip SHA256逻辑说明:先用本机算法从文件内容算出一个固定长度的哈希串,再把它和官方发布的哈希值做比对。只要两者一致,就能确认文件在下载过程中没有损坏。-Algorithm SHA256指定的是哈希算法,SHA256 是目前校验文件完整性的主流选择,比老旧的 MD5 安全得多,速度也够快。
参数说明:certutil命令中,-hashfile是固定参数,表示对指定文件做哈希计算,后面的SHA256是算法名,也可以换成SHA512(更慢但更稳)或MD5(仅用于老系统兼容,不建议)。PowerShell 的-Algorithm同样接受这些取值。比对时建议直接复制官方公布的哈希值,不要肉眼逐字符看,用文本对比工具或者直接把两串放进同一个终端窗口对比,否则容易看花眼。
这一步做完之后再解压,后面碰见任何环境问题都能放心排查自己的配置,而不是怀疑包有问题。哈希校验这件事说白了是个习惯,养成之后对任何下载的软件都会这么做,省下的时间远超校验本身花掉的十几秒。
3. 在 Windows x64 上安装 JDK 23:解压路径、JAVA_HOME 与 PATH
3.1 选定安装目录,避免三类常见路径问题
解压这个 zip 之前,先决定好它最终放在哪。我见过有人在桌面直接解压、跑通之后就把整个 JDK 目录扔在那里,后来项目交接时找半天找不到;还有人把 JDK 解压到了带空格的目录里,结果某些脚本执行%JAVA_HOME%\bin\java时被路径截断。这三个问题都出在“没有提前规划目录”上。
常见做法是建立一个集中的C:\java\目录,把不同版本的 JDK 都放在这个目录下面,例如C:\java\jdk-23。这样做的理由有两条:一是路径短且没有空格,兼容性最好;二是所有 JDK 版本都在同一个父目录下,后续做多版本切换非常方便。如果习惯用 D 盘,也可以换成D:\java\jdk-23,只要路径里没有空格、没有中文即可。
解压操作本身很简单,但注意一个细节:Windows 自带资源管理器右键解压通常会生成一个嵌套目录(比如解压后是jdk-23-windows-x64-bin\jdk-23.0.x\...),这会额外多一层目录,不方便管理。我一般会先用 PowerShell 看一下压缩包内部结构,再决定怎么解:
# 查看压缩包内第一层目录结构 tar -tf .\jdk-23-windows-x64-bin.zip | Select-Object -First 10逻辑说明:tar命令在 Windows 10 1803 之后的系统里已经内置,可以直接读取 zip 包内容列表。-t表示列出内容而非解压,-f指定文件名,Select-Object -First 10只取前 10 行输出,避免目录内容太多刷屏。
参数说明:如果输出显示第一层目录名就是你想要的,比如直接是jdk-23.0.x/,那解压后重命名一下即可;如果显示的是双层嵌套目录,解压后需要手动把内层目录移动出来。更直接的办法是用Expand-Archive解压,然后立刻用Rename-Item把目录名规范成jdk-23:
# 解压到 C:\java 目录 Expand-Archive -Path .\jdk-23-windows-x64-bin.zip -DestinationPath C:\java -Force # 如果解压出来的目录名带完整版本号,统一改成 jdk-23,方便后续配置 Rename-Item -Path "C:\java\jdk-23.0.x" -NewName "jdk-23"逻辑说明:Expand-Archive是 PowerShell 自带的压缩包解压命令,-DestinationPath指定目标目录,-Force表示如果目标目录已存在同名文件就覆盖。第二步把版本号目录统一成jdk-23是为了环境变量配置时不至于写一长串带小版本号的路径——升级小版本时只需要替换目录内容,环境变量不用改。
3.2 配置 JAVA_HOME 与 PATH:GUI 和命令行两种方式
解压只是把文件放到位,真正让系统认出来还需要配置环境变量。Java 工具链通过两个关键变量定位 JDK:JAVA_HOME和PATH。JAVA_HOME指向 JDK 安装根目录,是 Maven、Gradle、Tomcat 这类工具寻找 JDK 的重要依据;PATH则让java和javac命令可以在任何目录下直接执行。
先看 GUI 方式:右键“此电脑” → 属性 → 高级系统设置 → 环境变量。在“系统变量”区域新建JAVA_HOME,值填C:\java\jdk-23;然后在系统变量的Path中新建一行%JAVA_HOME%\bin,确定保存。这是最直观的方式,适合一台机器只配一次的场景。
但 GUI 方式在需要批量部署或重复操作时就显得低效,我更多时候用命令行写:
# 设置系统级 JAVA_HOME,需要管理员权限运行 PowerShell [Environment]::SetEnvironmentVariable("JAVA_HOME", "C:\java\jdk-23", "Machine") # 在系统级 Path 的末尾追加 %JAVA_HOME%\bin,避免覆盖已有值 $oldPath = [Environment]::GetEnvironmentVariable("Path", "Machine") $newEntry = "%JAVA_HOME%\bin" if ($oldPath -notlike "*$newEntry*") { [Environment]::SetEnvironmentVariable("Path", "$oldPath;$newEntry", "Machine") }逻辑说明:[Environment]::SetEnvironmentVariable是 .NET 的环境变量原生接口,比setx更可靠,因为setx有一个著名的问题——当你写入%JAVA_HOME%\bin时,它会把%JAVA_HOME%先展开成绝对路径再写入注册表,这会导致后续修改JAVA_HOME时Path里的老路径仍然指向旧目录,多版本切换时特别容易翻车。上面这段脚本用-notlike先判断目标值是否已在Path中,避免重复追加。
参数说明:SetEnvironmentVariable的第一个参数是变量名,第二个参数是变量值,第三个参数是作用范围。"Machine"表示系统级变量,需要管理员权限;改成"User"只对当前用户生效,不需要管理员权限。路径变量后追加;是 Windows 的列表分隔符,原有内容保留在前面。
如果你已经用setx配坏过,也别慌,打开 GUI 环境变量编辑器,把Path里重复的 JDK 条目清掉就行。清理完再跑一遍上面脚本,让系统回到正确状态。
3.3 解压后目录里哪些文件值得先看一遍
配置好变量后,建议花两分钟看一眼 JDK 目录里的结构,这能帮你快速定位很多问题。bin目录存放全部可执行命令,包括java.exe、javac.exe、jshell.exe;conf目录存放 JDK 自身的配置文件,比如安全策略、日志配置;lib目录存放类库和模块文件;legal目录是各类开源许可证文本;include目录是写 JNI 原生代码时需要引用的头文件——用不到可以忽略。
有一个文件值得打开看一眼:release文件,它位于 JDK 根目录,是一个键值对格式的配置文件,记录了当前安装版本的信息。在命令行执行:
type C:\java\jdk-23\releaseoutput 输出里会包含JAVA_VERSION="23"、OS_NAME="Windows"、OS_ARCH="x86_64"等字段。这个文件在排查环境问题时有奇效——当系统里装了多个 JDK,不确定当前生效的到底是哪个版本时,可以用它确认物理文件路径对应的真实版本号。很多环境问题看起来是“JDK 装了但跑不了”,实际是环境变量指向的目录里放的根本不是 JDK 23。
另外,bin目录下除了java.exe和javac.exe,还有javadoc.exe、jar.exe、jlink.exe等工具。做模块化镜像或精简运行时的时候,jlink几乎每天都在用;不过这里只做了解,不展开,后面的进阶部分会再提到它的用法。
4. 验证 JDK 23 安装成功:从 java -version 到一次真实编译
4.1 读懂 java -version 和 javac -version 的输出
环境变量配完,先开一个新终端窗口(注意:已经开着的旧窗口不会加载新环境变量,这是新手最容易忽略的点),然后执行最经典的验证命令:
java -version javac -version输出通常长这样:
java version "23.0.x" Java(TM) SE Runtime Environment (build 23.0.x+xx) Java HotSpot(TM) 64-Bit Server VM (build 23.0.x+xx, mixed mode, sharing) javac 23.0.x逻辑说明:java -version输出三行信息——第一行是版本号,第二行是运行时环境标识,第三行是 JVM 实现信息。javac -version只输出版本号和编译器标识。如果java有输出但javac报“不是内部或外部命令”,说明你的Path里只配了 JRE 或者配了别的 Java 运行时,JDK 的bin目录没有被正确加到Path中。
这里有个容易翻车的细节:如果系统里之前装过别的 Java 版本,java -version显示的可能是旧版本。用where java看一下实际命中的路径:
where java这条命令会列出所有能被Path找到的java.exe完整路径,排在最上面的就是当前默认使用的那个。如果最上面是C:\Windows\System32\java.exe或某个老目录,说明你的 JDK 23 不是默认版本,需要调整Path里条目顺序或者把不需要的 Java 相关路径清掉。这一步值得养成习惯,因为很多所谓“版本冲突”问题,最终查出来都是这里出了问题。
4.2 用一段最小代码完成本地编译与运行
java -version只能证明运行时存在,要证明编译器链路也正常,得实际编译一段代码。先用编辑器写一个最小示例:
public class VersionCheck { public static void main(String[] args) { System.out.println("Running on: " + System.getProperty("java.version")); System.out.println("Home: " + System.getProperty("java.home")); } }进入文件所在目录后,执行:
javac VersionCheck.java java VersionCheck第一次执行时,输出第一行应该显示Running on: 23,第二行显示你配置的JAVA_HOME路径C:\java\jdk-23。注意java.home是 JVM 实际上使用的 JDK/JRE 路径,而不是环境变量里写的值——这是个重要区别。如果这里输出的路径和环境变量不一致,说明某个工具或启动脚本在启动时覆盖了JAVA_HOME,或者在Path的更高优先级处存在另一个 Java 运行时。
顺手清理编译产物是个好习惯,javac会在当前目录生成VersionCheck.class文件:
del VersionCheck.class上面的验证流程虽然简单,但覆盖了编译器和运行时两条链路,比单纯java -version更有说服力。如果你想更快速地做试验,可以试试 JDK 自带的jshell,进入交互式环境直接输入 Java 表达式:
jshell然后在jshell>提示符后面输入System.getProperty("java.version"),回车即可看到输出。jshell不需要建类和 main 方法,非常适合验证 API 或做语法实验,我经常用它替代写测试类来快速确认某些新版本行为有没有变化。退出时输入/exit。
4.3 在 IDE 里确认当前生效的是同一份 JDK
命令行验证通过后,如果你日常用 IDE 开发,建议在 IDE 里也检查一遍。问题在于:IDE 往往自己管理了一整套 JDK 列表,比如自带的 JBR(JetBrains Runtime)或者其他已注册的 JDK,并不会自动跟随系统的JAVA_HOME变化。即使你命令行已经切到 JDK 23,IDE 项目可能还在用旧版本,运行时行为就和命令行不一致了。
以常见 IDE 为例,打开设置或项目结构对话框,在 SDK/Language Level 配置里手动添加 JDK 路径,直接指向C:\java\jdk-23。添加后检查一下项目语言级别是否设为与你需要的版本匹配——很多时候 SDK 选了 23,但 Language Level 还停在 17,编译时语法检查仍然按 17 来,代码里用了新语法就会标红。这两项必须同时一致,否则项目会出现“命令行能编译,IDE 里报错”的诡异现象。
顺带说一个实用习惯:IDE 里确认完版本后,用一次全量构建(Clean Build)代替增量构建,强制所有模块重新编译。这样能把缓存导致的“旧 class 文件残留”问题一次清掉,避免调试时跑的还是旧代码。
5. JDK 23 安装使用中的 5 个坑:现象、原因、解决办法
坑 1:java -version 显示的不是 JDK 23
现象:按前面步骤配置了JAVA_HOME和Path,但新开终端执行java -version,输出的却是1.8.0_xxx或者别的版本号。
原因:系统的Path中某个更靠前的目录里存在另一个java.exe。最常见的是操作系统自带的 Java Web Start 残留、第三方软件内嵌的 JRE、或者其他开发工具链写入的路径。Windows 在执行命令时按Path的顺序从上到下查找,排在前面的先命中,你的 JDK 23 路径排在别人后面,根本没被找到。
解决:先执行where java列出全部命中路径,确认哪些是多余的。然后在环境变量编辑器里,把%JAVA_HOME%\bin移动到Path列表的最上方,或者直接删除其他 Java 相关条目。清理完重新打开终端再执行java -version,这时输出的必须和C:\java\jdk-23\bin\java.exe -version完全一致。
坑 2:用 setx 配置环后 Path 里出现重复且超长
现象:之前用setx命令配置过Path,后来发现环境变量里的Path越来越长,同一个 JDK 路径出现好几遍,偶尔还报某些命令找不到。
原因:setx在写入变量时会把%JAVA_HOME%这类引用展开成实际路径字符串,然后直接覆盖或追加到注册表。如果你在已经崩溃的Path上反复执行追加操作,旧值不会自动去重,只会不断叠加,最终形成大量重复条目。这会让一些对Path长度敏感的老软件直接罢工。
解决:打开 GUI 环境变量编辑器,手动把Path里重复的 BIOS 条目全部清掉,只保留一份完整路径。之后的更新用[Environment]::SetEnvironmentVariable或 GUI 操作,直接改回用setx的习惯。日常运维中“少用 setx 改 Path”是一条值得记牢的经验。
坑 3:JAVA_HOME 配置了但软件不识别
现象:命令行里java -version正常,但 Maven、Gradle、Tomcat 等工具仍然报找不到 JDK,或者启动脚本提示JAVA_HOME未设置。
原因:这些工具在启动脚本里大量依赖JAVA_HOME变量,并通过它的值定位 JDK。常见问题是改成了用户级变量,但服务是以系统服务方式启动的——系统服务不会加载用户级环境变量;或者工具进程是在环境变量修改之前启动的,需要重启进程才能读取新值。
解决:先确认你修改的是用户级还是系统级变量:在管理员终端里执行echo %JAVA_HOME%,如果为空则说明系统级没配上。改为系统级JAVA_HOME后,重启所有相关进程和 IDE。对于无法重启的系统服务,新建一个不会自动退出的用户进程去继承新环境变量是最快的验证方法。还有一个很隐蔽的原因:JAVA_HOME的值最好不要带尾部的\,也不要加bin后缀,有些严格的脚本会因此判断路径无效。
坑 4:解压或移动 JDK 目录时提示文件被占用
现象:想清理或移动C:\java\jdk-23目录,却提示“文件被另一进程使用,无法删除”或“无法访问”。
原因:某个正在运行的 Java 进程(如 IDE 的后台服务、Spring Boot 调试实例、或者javaw.exe)正在使用 JDK 目录内的 DLL 或可执行文件,运行时加载的库文件被系统锁定,删除自然失败。
解决:先打开任务管理器,找到所有名称包含java或javaw的进程,确认哪些是自己启动的服务,关掉后再删除或移动目录。如果是 IDE 的内置终端或编译进程,把 IDE 整体退出再处理。这个坑在多人共用服务器场景下尤其明显——别人挂着你的 Java 服务,你急着升级 JDK,结果目录被锁死。严格的工作习惯是在升级前先扫码确认没有 Java 进程在运行,再动目录。
坑 5:编译含中文字符的源码乱码或报错
现象:源码文件里有中文注释,javac编译时报“不可映射的字符”或“编码 GBK 的不可映射字符”,编译干脆失败。
原因:Windows 中文版系统默认编码是 GBK(现在的新版本终端多改为 UTF-8),而源码文件用 UTF-8 保存。javac在没有显式指定编码时,会按系统默认代码页读取源码文件,UTF-8 的中文字节被误读为 GBK,自然就会乱码报错。
解决:编译时显式指定编码:
javac -encoding UTF-8 VersionCheck.java逻辑说明:-encoding UTF-8是javac的标准参数,告诉编译器源码文件的字符集是 UTF-8,不再猜测系统默认编码。参数值必须和源码文件实际保存的编码一致,如果你源码是用 GBK 存的就不用加,或改成-encoding GBK。
参数说明:强烈建议所有 Java 源码文件统一用 UTF-8 编码保存,并在项目根目录放一个.editorconfig文件来固化编码设置。这在多人协作时能避免大量无意义的乱码 diff。另一个习惯是尽量不要把 JDK 放在含中文的目录路径里——比如D:\工具\JDK23,这类路径在某些旧工具或脚本里会触发编码问题,而路径本身并不会报错,排查起来非常隐蔽。我见过的最诡异案例是某构建脚本在扫描源码文件时,把所有非 ASCII 路径的文件全部跳过,最后查了整整一天才发现是路径里的中文目录名导致的。
6. 进阶用法:把 bin.zip 变成可切换、可复现的 JDK 资源池
装完一个 JDK 23 只是开始。真正让 zip 版 JDK 发挥价值的使用方式,是把多个版本放在同一个父目录下,用统一的方式切换,并且把整个过程脚本化,做到新环境五分钟左右能复现。我自己的做法是先在C:\java下维护一份全部版本的解压目录,然后用 Windows 目录符号链接固定一个“当前默认”的入口:
mklink /D C:\java\jdk-current C:\java\jdk-23逻辑说明:mklink /D创建的是目录符号链接,C:\java\jdk-current并不真实存储文件,只是指向jdk-23的入口。之后把环境变量JAVA_HOME固定写成C:\java\jdk-current,以后切换版本时,只需要删掉这个链接重新建一个,指向另一个版本目录即可,环境变量不用改动。这一招在频繁切换跨版本项目的场景里非常实用。
参数说明:/D表示创建目录链接而非文件链接;目标路径必须使用绝对路径。删除链接用rmdir C:\java\jdk-current,注意不是del。创建链接不一定需要管理员权限,但在某些系统上要求先开启开发者模式或管理员终端,这个取决于具体 Windows 版本策略,如果提示权限不足就用管理员终端执行。
配合这条技巧,我通常还把安装流程做成了一个 PowerShell 脚本,输入 zip 包路径即可完成“解压→重命名→写环境变量→验证”四步:
param( [string]$ZipPath, [string]$InstallBase = "C:\java", [string]$VersionName = "jdk-23" ) $ErrorActionPreference = "Stop" $targetDir = Join-Path $InstallBase $VersionName # 解压到临时目录 Write-Host "解压中..." Expand-Archive -Path $ZipPath -DestinationPath "$InstallBase\tmp_extract" -Force # 处理嵌套目录,把实际 JDK 目录重命名为目标版本名 $extracted = Get-ChildItem "$InstallBase\tmp_extract" -Directory | Select-Object -First 1 if (Test-Path $targetDir) { Remove-Item $targetDir -Recurse -Force } Rename-Item $extracted.FullName $targetDir Remove-Item "$InstallBase\tmp_extract" -Recurse -Force # 写入系统级环境变量 $binDir = Join-Path $targetDir "bin" [Environment]::SetEnvironmentVariable("JAVA_HOME", $targetDir, "Machine") $oldPath = [Environment]::GetEnvironmentVariable("Path", "Machine") if ($oldPath -notlike "*$binDir*") { [Environment]::SetEnvironmentVariable("Path", "$oldPath;$binDir", "Machine") } # 验证 & (Join-Path $binDir "java.exe") -version逻辑说明:这个脚本把安装链路固化成了参数化流程,$ZipPath是本地已下载好的 zip 包路径,$InstallBase是所有 JDK 版本的父目录,$VersionName是解压后的目录名。全程不需要手动右键解压、不需要手改环境变量。&运算符直接调用指定路径下的java.exe -version做最终验证,不依赖Path是否已刷新。
参数说明:脚本需要管理员权限运行(因为写入了Machine级变量)。如果只想对当前用户安装,把SetEnvironmentVariable的最后一个参数从"Machine"改成"User",并把Path读取也同步改成"User"即可。$ErrorActionPreference = "Stop"是让任何一步报错时立即中止脚本,避免执行到一半留下半残状态。
把这些习惯固定下来之后,我很少再被 JDK 安装问题卡住。以前我也图省事,直接把 zip 解压到桌面就开跑,后来同事接手时找不到路径、IDE 和命令行版本不一致、环境变量里一堆冗余条目……这些血泪经验让我意识到,JDK 安装不是“解压就能用”的一次性动作,而是一个应该被固化成基础设施的流程。现在每换一次环境,我都走同一套脚本化流程,五分钟左右就把环境拉齐。希望这套思路对你也有帮助。
本文还有配套的精品资源,点击获取