JDK 和 Maven 在 Windows 下的安装和配置,算是 Java 开发里最基础但也最容易出幺蛾子的一环。不少新手甚至工作一两年的同事,都可能在环境变量、版本兼容这些地方卡过壳。这篇文章就把我多年来在 Windows 上折腾 JDK 和 Maven 的经验完整梳理一遍,从下载到配置,从原理到踩坑,一步步讲清楚,争取让你看完就能一次搞定。
1. 环境准备与版本选型思路
1.1 先搞清楚 JDK 和 Maven 各自扮演什么角色
在动手下载之前,先把这两个东西的角色理清楚,后面配置起来思路会顺畅很多。
JDK 是 Java 开发工具包,它不光包含 Java 运行时环境,还带了编译器、调试工具、打包工具等一系列开发必需品。你可以把 JDK 理解为"生产 Java 程序的整套工厂",而 Maven 则是"工厂里的自动化流水线管理员"。Maven 本身也是用 Java 写的,所以它的运行依赖 JDK,必须先装 JDK 再装 Maven,这个顺序不能反。
Maven 解决的核心痛点有两个。第一个是依赖管理:以前做 Java 项目,要把各种 jar 包手动下载、复制到 lib 目录,版本冲突更是噩梦;Maven 通过仓库机制,你只需要在配置文件里声明依赖,它自动帮你下载和管理。第二个是标准化构建:编译、测试、打包、部署这一整套流程,Maven 用约定的生命周期统一搞定。
搞清楚这两层关系,你就明白为什么网上教程都要求先配好 JAVA_HOME,再配置 MAVEN_HOME,因为 Maven 启动时会去找 Java 环境,找不到就直接报错退出。
1.2 如何选择合适的 JDK 版本
Windows 下选 JDK 版本,我见过太多人在这里踩坑。选版本不能只看"最新",更要看你的项目需求。
目前市面上主流的有 Java 8、Java 11、Java 17 这几个 LTS 长期支持版本,Java 21 也已经发布。如果你的项目是维护老系统,Java 8 是绝对主流,很多传统企业的遗留系统还停在 JDK 8 上;如果是新项目,建议至少 Java 11 起步,能上 Java 17 就直接上,因为 Java 17 在性能、语法、垃圾回收器方面都有明显提升。
还有一个容易被忽略的问题:Oracle JDK 和 OpenJDK 的抉择。Oracle JDK 从 Java 8u211 版本开始,个人使用免费,但企业商用需要付费授权;OpenJDK 则完全开源免费。对绝大多数开发者来说,选 OpenJDK 或者基于 OpenJDK 的发行版(比如一些社区维护的版本)完全够用,没必要为了心理安慰去冒险用 Oracle JDK 商用。
我个人的建议是:去 OpenJDK 官网或者靠谱的镜像站下载,选 LTS 版本,对应 Windows x64 的 .zip 或 .msi 安装包都可以。zip 版更灵活,卸载时直接删文件夹;msi 版会自动配好注册表和环境变量,省事但不够透明。我自己习惯用 zip 包,因为配置过程完全可控,也方便多版本切换。
1.3 Maven 版本搭配的原则
Maven 版本的选择相对简单,核心原则是:Maven 3.6.x 以上版本兼容 JDK 8 到 JDK 17,Maven 3.9.x 对 JDK 17 和 JDK 21 支持更完善。如果你用的是 JDK 8 环境,也不要刻意用老版本 Maven,3.6.3 以上都没问题。
Maven 官网提供 Binary zip archive 和 Binary tar.gz archive 两种格式,Windows 下直接下 Binary zip archive。下载页面看准 ".zip" 后缀的包,别下成 Source 包,那个是源码,不能直接运行。
这里有个很多人不知道的小细节:Maven 不需要安装程序,解压即用。整个 Maven 就是一个文件夹,只要把路径配好,它就能跑起来。这种绿色软件的好处是,你可以同时保留多个 Maven 版本,随时切换。
1.4 目录规划与多版本共存思路
强烈建议你在 C 盘以外的盘符建一个统一的开发工具目录,比如D:\devtools\,然后分别创建D:\devtools\jdk和D:\devtools\maven目录,把解压后的文件放进去。
为什么特意强调目录规划?因为 Windows 下最容易出的问题就是路径里有空格或中文。比如你把 JDK 装到C:\Program Files\Java\jdk-17,这个路径虽然能用,但在某些老旧脚本、批处理文件里,空格就会引发奇怪的问题。更别用中文目录名,少数框架和插件在解析路径时遇到中文会直接乱码。
多版本共存的做法也很简单:用不同的文件夹名区分版本,比如D:\devtools\jdk8和D:\devtools\jdk17,需要切换时只需修改 JAVA_HOME 环境变量指向目标目录。这个思路同样适用于 Maven,如果你有老项目必须用 Maven 3.5,完全可以保留两个 Maven 目录。
2. JDK 安装与核心配置详解
2.1 JDK 解压安装的正确姿势
以 zip 包为例说明安装流程。下载完成后,用解压工具解压到D:\devtools\jdk目录。解压完成后,你会看到一个类似jdk-17.0.8的文件夹,里面是 bin、conf、include、jmods、legal、lib 这些子目录。
如果你是下载的 .msi 安装包,双击安装时会自动解压到系统目录并配置环境变量。但这里我要多说一句:msi 安装方式虽然省事,但它生成的环境变量配置比较隐蔽,后期如果你想改路径或者换版本,反而要多几步操作。zip 包完全手动控制,出问题也好排查。
解压完成后,先验证一下目录结构是否正确。打开文件夹,找到bin目录,里面应该能看到java.exe和javac.exe这两个最关键的可执行文件。千万注意,如果你在 bin 里找不到javac.exe,说明你下载的不是 JDK,而是 JRE,那样没法编译 Java 代码。
2.2 环境变量配置的底层逻辑
真正让无数人困惑的是环境变量配置。这里我把原理讲透,你就不会再被各种教程绕晕。
Windows 环境变量分用户变量和系统变量两种。系统变量对所有用户生效,修改它需要管理员权限;用户变量只对当前用户生效,不需要额外权限。开发工具的环境变量配置在用户变量里就够用,没必要动系统变量,这样更安全。
需要配置的核心是三个变量:
- JAVA_HOME:指向 JDK 安装目录
- Path:在原有值的基础上追加 JDK 的 bin 目录
- CLASS_PATH:早期教程会配置这个,现在其实不需要了
打开环境变量编辑器的方法:右键"此电脑"→"属性"→"高级系统设置"→"环境变量"。在"用户变量"区域点击"新建",变量名填JAVA_HOME,变量值填你的 JDK 目录路径,比如D:\devtools\jdk\jdk-17.0.8。
注意:JAVA_HOME 一定要指到 JDK 的具体版本目录,而不是只到 jdk 这一层。很多工具(包括 Maven、Tomcat、Gradle)依赖这个变量来定位 Java 环境,如果你指错了层级,后面全都会报错。
然后找到 Path 变量,点击编辑。Win10 和 Win11 的环境变量编辑器是列表形式的,直接点"新建"添加%JAVA_HOME%\bin即可。这里特意用%JAVA_HOME%来引用,而不是写完整路径,这样以后切换 JDK 版本时,只需要修改 JAVA_HOME,Path 不用动。
至于CLASS_PATH,我明确建议你不需要配置。这个东西是 JDK 1.4 时代的遗留产物。现代 JDK 和构建工具会自动处理类路径,配置了反而可能干扰项目运行。网上有些老教程还在教人配 CLASS_PATH,直接跳过就行。
2.3 验证 JDK 是否配置成功
配置完环境变量,最关键的一步是验证。先关掉所有已经打开的命令行窗口,重新打开一个新的 cmd 窗口,依次执行两个命令:
java -version javac -version如果输出类似这样的结果,说明 JDK 配置成功:
java version "17.0.8" 2023-07-18 LTS Java(TM) SE Runtime Environment (build 17.0.8+9-LTS-211) Java HotSpot(TM) 64-Bit Server VM (build 17.0.8+9-LTS-211, mixed mode, sharing)如果提示"不是内部或外部命令",一般有两种可能:一是 Path 变量没配置正确,二是修改完环境变量后没有重开 cmd 窗口。老版本的 cmd 窗口在启动时读取环境变量,之后修改的变量不会自动生效,必须新开窗口才能加载最新的环境变量。
还有一种情况是 java -version 能显示,但 javac 提示找不到。这种情况通常是你的 Path 里同时存在多个 Java 的路径,系统优先找到了 JRE 而不是 JDK 的 bin。排查方法很简单:执行where java命令,它会列出所有被找到的 java.exe 路径,看看排第一个的是不是你刚才配置的那个。
2.4 实战小测试:写一个 Hello World 确认编译链完整
环境变量配好不等于万事大吉,最好再实际编译运行一次程序确认整条链路通畅。在任意目录新建一个Hello.java文件,内容如下:
public class Hello { public static void main(String[] args) { System.out.println("JDK 配置成功,可以正常编译运行!"); } }在命令行中进入该目录,依次执行:
javac Hello.java java Hello看到输出"JDK 配置成功,可以正常编译运行!"就说明 JDK 的编译链全部正常。这一步看起来多余,但它能帮你提前暴露问题。我就遇到过明明 java -version 正常,但 javac 实际是坏的情况,就是因为系统里装了多个 JDK,版本混乱。实际编译测试是最可靠的检验方式。
3. Maven 安装与仓库配置实战
3.1 解压与基础配置
Maven 的安装同样采用绿色解压方式。下载好的 zip 包解压到D:\devtools\maven\目录,你会得到一个类似apache-maven-3.9.6的文件夹。
和 JDK 一样,需要配置两个环境变量:MAVEN_HOME指向 Maven 目录,然后在 Path 中追加%MAVEN_HOME%\bin。变量值建议写成D:\devtools\maven\apache-maven-3.9.6。
配置完成后重开 cmd,执行mvn -v验证:
Apache Maven 3.9.6 (bc2360e076d871d84e09e0a1f3b7e1f) Maven home: D:\devtools\maven\apache-maven-3.9.6 Java version: 17.0.8, vendor: Oracle Corporation, runtime: D:\devtools\jdk\jdk-17.0.8注意看最后一行,Maven 会显示它当前使用的 Java 版本。如果你发现这里显示的 Java 版本和实际不符,说明 JAVA_HOME 配置有偏差或者系统 Path 里有其他 Java 抢先被找到了。Maven 只看 JAVA_HOME 和 Path 里的 java 指令,不看系统里装了多少个 JDK。
3.2 配置本地仓库路径
Maven 默认会把依赖 jar 包下载到用户目录下的.m2\repository文件夹。这个默认路径在 C 盘,依赖下载多了以后会占用好几个 GB 空间,而且万一 C 盘空间紧张或者系统重装,这些缓存就全没了。
更合理的做法是在 Maven 安装目录外单独建一个仓库目录,比如D:\devtools\maven-repository。这个目录最好和 Maven 安装目录分开,因为后期升级 Maven 时,如果仓库在安装目录里,升级时容易被一并清理。
修改settings.xml文件,它在 Maven 安装目录下的conf文件夹里。找到<localRepository>标签,默认是被注释掉的,取消注释并修改为:
<localRepository>D:\devtools\maven-repository</localRepository>修改后保存,再次执行mvn help:effective-settings命令,在输出的内容里搜索 localRepository,就能看到你的配置是否生效。这个命令是验证配置的利器,比瞎猜强多了。
3.3 配置阿里云镜像加速下载
这个步骤在咱们这基本属于必需品,因为 Maven 中央仓库服务器在国外,直接下载依赖的速度经常让人崩溃,尤其是拉取大体积 jar 包时,卡个十几分钟是常事。
在settings.xml的<mirrors>标签内添加镜像配置:
<mirror> <id>aliyunmaven</id> <name>阿里云公共仓库</name> <url>https://maven.aliyun.com/repository/public</url> <mirrorOf>central</mirrorOf> </mirror>这里解释一下配置里各标签的含义:mirrorOf写 central,表示只对中央仓库生效镜像,其他自定义仓库不受影响;url指向阿里云的公共仓库,它聚合了中央仓库和常用的公共仓库,覆盖面广且更新及时。
配置完以后,新建一个普通项目执行一次mvn clean compile,观察下载速度。正常情况下,你会在日志里看到依赖 jar 包快速下载完成的记录,而不是之前那样长时间卡在 "Downloading..." 的状态。记住,阿里云公共仓库是 https 协议,如果项目里有特殊的私服仓库,镜像配置要调整成针对性的规则,不能盲目 mirrorOf 设为*。
3.4 JDK 版本与编译参数设置
Maven 默认使用 JAVA_HOME 对应的 JDK 版本进行编译,但这不代表项目构建总会用你期望的版本。如果你的系统环境是 JDK 17,但项目要求以 Java 8 语法编译,就必须在项目的pom.xml中显式指定编译版本。
在pom.xml中加入:
<properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties>这里有一个常见误区:maven.compiler.source和target只控制编译时的源码语法级别和目标字节码版本,它并不等于运行时用的 JDK。如果你用 JDK 17 编译 target 为 8 的代码,运行时仍需要 JRE 8 或更高版本。而且 JDK 17 编译 target 8 时会提示"源选项 8 已过时",这是正常的,不影响使用。
如果你的电脑上同时装了 JDK 8 和 JDK 17,而 Maven 仍用 JDK 17 来编译,可以通过设置JAVA_HOME临时切换,也可以直接在 Maven 的mvn.cmd前设置环境变量。但最推荐的方式还是用 IDE 的 Project Structure 指定项目 SDK,这是后话,这里不展开。
4. 实操中高频踩坑与排查方案速查
4.1 命令找不到的经典场景与解法
"不是内部或外部命令"错误,多半是 Path 配置错误。先执行echo %JAVA_HOME%看变量是否输出正确路径,再执行echo %Path%看%JAVA_HOME%\bin是否在里面。有个小提示:在 cmd 里用echo %Path%时,系统会显示展开后的完整路径,你直接找 JDK 的 bin 目录路径是否存在就行。
还有一类隐蔽情况:电脑上装了某些软件会自己往 Path 里加 Java 的路径,比如某些 IDE 自带 JRE。这样即使你配置了 JAVA_HOME,命令行执行java时,系统按 Path 顺序找到的却是其他版本的 java。排查方式就是执行where java把所有位置列出来,确认排在最前面的是不是你想要的那个。
mvn 不是内部或外部命令,排查思路同上,先确认MAVEN_HOME配置正确,再看 Path 里有没有%MAVEN_HOME%\bin。另外注意,MAVEN_HOME 和 M2_HOME 是历史遗留的两种命名,新版本 Maven 用 MAVEN_HOME 即可,不要同时配置两个,避免冲突。
4.2 JAVA_HOME 与 Path 互相影响问题
JAVA_HOME 理论上应该和 Path 中的 java 指令来源一致。如果出现java -version显示一个版本,而 Maven 构建时又用另一个版本,大多是因为 Path 里的某个 java.exe 和 JAVA_HOME 不一致。
解决办法:打开 Path 编辑,把所有指向 java.exe 的条目都检查一遍。比如有些软件会自动添加C:\Program Files\Common Files\Oracle\Java\javapath到 Path,这个路径指向系统安装的公共 JRE,和你的 JAVA_HOME 无关。如果它排在前面,就会优先被执行。
最稳妥的做法是:把%JAVA_HOME%\bin移到 Path 列表最顶部。在 Windows 环境变量编辑器里,选中条目后可以上移。这样能确保命令行执行 java 时优先使用 JAVA_HOME 指定的版本。
4.3 Maven 下载依赖失败的排查路径
依赖下载失败是最让人抓狂的问题之一。常见报错有Could not transfer artifact、PKIX path building failed、Connection reset等。
首先判断是不是网络问题。直接访问中央仓库地址,看能否打开。如果打不开,那你的镜像配置就非常重要了。把 settings.xml 里的镜像换成阿里云后重试。
如果镜像配置了对,依然报 SSL 证书错误,那就是 JDK 版本自带的 CA 证书库和镜像站的证书不匹配。这种情况常见于 JDK 8 低版本访问某些新版 HTTPS 镜像站,解决办法有两个:升级 JDK 版本,或者用 HTTP 协议的镜像地址(不推荐)。
还有一种隐性坑:settings.xml文件编码问题。如果你用记事本编辑过 settings.xml 并保存成了 UTF-8 with BOM 格式,Maven 解析时可能直接报错。强烈建议用 VS Code 或 Notepad++ 编辑,编码选 UTF-8 无 BOM 格式。
4.4 环境变量修改后不生效的处理技巧
这是老生常谈但从来不过时的问题。Windows 的资源管理器、命令行窗口、IDE(特别是已经打开的),在启动时就会把当时的环境变量读入内存。你修改了环境变量,它们不会自动刷新,必须关掉重新打开。
但如果你重开了 cmd 还是不行,还有一个隐藏技能:执行refreshenv命令。这个命令来自 Chocolatey 包管理器,如果你没装 Chocolatey,可以使用 PowerShell 的方式:在 PowerShell 中执行$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User"),手动刷新当前会话的 Path。
其实最简单粗暴的办法永远有效:重启电脑。虽然听起来愚笨,但对于环境变量死活不生效的情况,重启后所有进程都会拿到最新的环境变量。
4.5 常见问题速查表
| 症状 | 可能原因 | 排查/解决 |
|---|---|---|
| java -version 正常,javac 找不到 | Path 中 JRE 优先于 JDK | 检查 where java,调整 Path 顺序 |
| mvn -v 提示找不到 | MAVEN_HOME 或 Path 配置错误 | 验证变量值,确认 bin 路径存在 |
| 依赖下载极慢 | 未配置国内镜像 | settings.xml 添加镜像源 |
| 依赖下载失败 SSL 报错 | 镜像 HTTPS 证书不匹配 | 换 JDK 版本或换镜像地址 |
| Maven 编译报"不支持发行版本" | pom.xml 未指定 compiler 版本 | 显式设置 source/target |
| 中文路径导致项目编译异常 | 项目路径含中文目录 | 项目放在英文路径下 |
| settings.xml 修改后不生效 | 编辑格式问题或修改错文件 | 检查用户级 vs 全局级 settings |
5. 进阶配置与多版本切换技巧
5.1 利用 Maven settings.xml 提升日常效率
Maven 的 settings.xml 其实分为两种级别:全局配置在 Maven 安装目录的 conf 文件夹下,用户配置在%USERPROFILE%\.m2\settings.xml。用户配置优先级高于全局配置,意味着你可以不改安装目录,只维护用户级配置,升级 Maven 时配置也不会丢。
日常开发中我会在用户级 settings.xml 里额外配置一项:<offline>false</offline>明确允许在线下载,同时设置<interactiveMode>true</interactiveMode>。还有自定义属性<properties>配合 profile 使用,比如针对不同 JDK 版本定义不同的maven.compiler.source值。
需要多提一嘴的是<profiles>标签。你可以在里面定义一个 activeByDefault 的 profile,统一设置 jdk 版本检查和编码方式。比如:
<profiles> <profile> <id>jdk-17</id> <activation> <activeByDefault>true</activeByDefault> </activation> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> </properties> </profile> </profiles>这样一来,几乎所有项目都会默认用 JDK 17 的编译参数,省去每个项目都在 pom.xml 里重复配置的麻烦。
5.2 IDEA 与命令行环境的环境变量差异
用集成开发环境(比如常见的 Java IDE)时要注意,IDE 内部运行 Maven 时,可能不会完全继承你在命令行配置的环境变量。有些 IDE 有自己独立的"Maven 设置"面板,它会优先使用面板里指定的 Maven home path、用户设置文件和本地仓库路径。
所以我建议:无论命令行还是 IDE,都保证指向同一个 Maven 目录和同一个 settings.xml。这样你在命令行执行mvn clean package和 IDE 里的构建行为完全一致,不会出现命令行能编译、IDE 里报错,或者反过来这种精神分裂的情况。
在 IDE 里配置 Maven 时,有一个小技巧:把本地仓库路径、镜像配置都设置好以后,先打开 Maven 面板刷新一次,确保 IDE 成功加载了新的 settings.xml。如果配置写错了,IDE 通常会提示"Settings file is invalid"之类的错误,这时候排查语法问题就行。
5.3 Windows 下多 JDK 版本切换的封装脚本
假设你电脑上同时装了 JDK 8 和 JDK 17,不想每次切换都手动改环境变量,可以写一个简单的批处理脚本,放在桌面或任意目录下调用。
新建switch-jdk.bat文件,内容如下:
@echo off echo 请选择要切换的 JDK 版本: echo 1. JDK 8 echo 2. JDK 17 set /p choice=请输入序号: if "%choice%"=="1" ( setx JAVA_HOME "D:\devtools\jdk\jdk-8u392" echo 已设置 JAVA_HOME 为 JDK 8 ) else if "%choice%"=="2" ( setx JAVA_HOME "D:\devtools\jdk\jdk-17.0.8" echo 已设置 JAVA_HOME 为 JDK 17 ) else ( echo 输入无效 ) pause注意,setx命令设置的是永久环境变量,但当前命令行窗口不会立即生效,需要新开窗口才能使用。如果你想当前窗口也生效,需要用set JAVA_HOME=...临时设置。这个脚本只是简化操作,原理还是改环境变量。
5.4 让 Maven 同时服务于多 JDK 项目的构建策略
一个项目如果需要用 JDK 8 编译,而另一个项目需要 JDK 17,除了手动切换 JAVA_HOME 之外,更优雅的方式是使用 Maven Toolchains 插件。简单来说,它允许你在同一台机器上让 Maven 自动选择匹配的 JDK 来执行编译。
在用户级 settings.xml 中加入:
<pluginGroups> <pluginGroup>org.apache.maven.plugins</pluginGroup> </pluginGroups>然后在项目 pom.xml 中配置:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-toolchains-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <goals> <goal>toolchain</goal> </goals> </execution> </executions> <configuration> <toolchains> <jdk> <version>17</version> </jdk> </toolchains> </configuration> </plugin> </plugins> </build>同时在toolchains.xml中指明 JDK 路径。这种方式适合团队协作时有统一构建要求,但对单机个人开发来说,手动切换 JAVA_HOME 其实已经够用,不必为了炫技增加复杂度。
6. 写在最后的个人实操体会
说句实在话,JDK 和 Maven 的安装配置看起来是初级内容,可我在带新人或者帮同事排查环境问题时,发现大量问题都出在最基础的环节。有人在 Path 里堆了好几个 Java 路径,有人用记事本改 settings.xml 导致乱码,还有人根本不看 Maven 输出的错误日志,全靠猜。
我个人的习惯是:所有开发工具一律用绿色解压版,所有路径放到 F 盘或 D 盘的一个固定目录,环境变量统一配置在用户变量,并且坚持每次配置文件改动后用命令行验证。这套习惯帮我省去了无数重复排查的时间。
最后再分享一个容易被忽视的小技巧:配置完环境变量后,不只是重开 cmd,最好把后台运行的资源管理器窗口也重启一下。因为如果你是通过资源管理器启动 IDE 或者某些工具,它们继承的可能是旧的环境变量。按Ctrl + Shift + Esc打开任务管理器,重启资源管理器进程,或者干脆注销一次再登录,环境变量才会非常彻底地刷新干净。