)
一、写在前面为什么你要看这篇相信很多同学和我一样遇到 IDEA 控制台中文乱码第一反应也是百度 / Google 搜到的 90% 答案就是把 IDEA 里所有 encoding 改成 UTF-8再加一句-Dfile.encodingUTF-8。我照做了Settings 里 Global / Project / Properties 全改成 UTF-8VM 参数里也加上了-Dfile.encodingUTF-8。结果呢Maven 编译还是一坨乱码[INFO] ·з һ עδа javac ܻע ָٰһ (-processor) ָ· (--processor-path, --processor-module-path) ʽע (-proc:only, -proc:full) ʹ -Xlint:-options شϢ ʹ -proc:none ע正确非乱码显示[INFO] 由于在类路径中发现了一个或多个处理程序因此启用了 批注处理。未来发行版的 javac 可能会禁用批注处理 除非至少按名称指定了一个处理程序 (-processor) 或指定了搜索路径 (--processor-path, --processor-module-path) 或显式启用了批注处理 (-proc:only, -proc:full)。 可使用 -Xlint:-options 隐藏此消息。 可使用 -proc:none 禁用批注处理。如果你也是JDK 18 及以上我是 JDK 22 IDEA 2025.2.1 中文 Windows那这篇文章就是为你写的——问题根本不在file.encoding。上面那串其实是 javac 的常规提示过时 API、注解处理器相关本身无害只是被编码错乱显示成了乱码。二、核心认知Java 的编码是“分层”的一个中文字符从内存到屏幕中间要过三关每一关用的字符集都可以独立设置、互不影响环节控制的属性中文 Windows 上的默认值① 字符串 → 字节写出去sun.stdout.encoding/sun.stderr.encoding跟随控制台代码页 936 / GBK② 文件 / 默认字符集file.encodingJDK 18 默认就是UTF-8JEP 400③ 字节 → 字符显示出来IDEA 控制台的编码设置你设的 UTF-8乱码的本质一句话第 ① 层用 GBK 把字编码成字节第 ③ 层却用 UTF-8 去解码对不上 →。而第 ① 层在 Windows 上根本不跟file.encoding走它跟的是控制台代码页codepage。中文 Windows 默认“非 Unicode 程序”语言环境是中国代码页 936 GBK。JVM 一启动就读这个代码页把System.out的输出编码设成 GBK。Maven 的[INFO]、javac 的“注: …”都属于System.out.println出来的字节自然就是 GBK。三、所以为什么-Dfile.encodingUTF-8没用因为它只钉住了第 ② 层默认字符集。而在 JDK 18 上这层本来就是 UTF-8——你加了等于没加。真正打印走的第 ① 层sun.stdout.encoding你压根没碰它依旧是 GBKMaven 照样吐 GBK 字节IDEA 照样按 UTF-8 解 → 还是乱码。还有一个常见坑很多人把-Dfile.encodingUTF-8加在了 IDEA 自己的 VM Options 里那只作用于 IDEA 这个软件本身传不到它 fork 出来的 Maven 子进程。四、根因图解一句话总结图中逻辑IDEA 控制台只是字节接收器它老老实实按 UTF-8 解码收到的字节并不会去“猜”字节原本是什么编码。上游 Maven 吐 GBK它无论如何都会错显。问题在上游输出方JVM 的 stdout 编码得在源头改对。五、根治方案用 JAVA_TOOL_OPTIONS推荐JAVA_TOOL_OPTIONS是一个环境变量由 JVM 启动器在任何一个 Java 进程启动的最早期自动读取把它的值自动拼到该 JVM 的启动参数里。这意味着不管你跑的是java -jar、javac、mvnMaven 本身也是 Java 程序、IDEA 帮忙起的 Maven 子进程、还是你的 Spring Boot 应用——每一个新 JVM 都会自动带上你设的-D参数一处配置、全局生效。操作步骤此电脑 → 右键 → 属性 → 高级系统设置 → 环境变量在“用户变量”或系统变量里新建变量名JAVA_TOOL_OPTIONS变量值-Dfile.encodingUTF-8 -Dsun.stdout.encodingUTF-8 -Dsun.stderr.encodingUTF-8确定重启 IDEA再跑mvn clean compile/ 运行程序中文正常。三个参数分别干嘛-Dfile.encodingUTF-8钉住默认字符集JDK 18 本来就是显式更稳也管 javac 读源码的默认编码。-Dsun.stdout.encodingUTF-8钉住System.out→ Maven 的[INFO]、println正常。-Dsun.stderr.encodingUTF-8钉住System.err→ 编译错误 / 警告也正常。核心就是后两个它们把“输出流编码”从 GBK 强制成 UTF-8与 IDEA 的 UTF-8 解码对上。小提示设了之后每次 JVM 启动会在 stderr 打一行Picked up JAVA_TOOL_OPTIONS: ...这是正常提示不是报错别慌。六、其他可选 / 补充方案1. 只针对 Maven不配全局环境变量Settings → Build, Execution, Deployment → Build Tools → Maven → Runner → VM Options填上面那整组三个参数。2. 只针对运行你的程序Run → Edit Configurations → 你的配置 → VM options填同样三个参数想一劳永逸就改Edit configuration templates → Application → VM options。3. 让 javac 读源码也明确用 UTF-8Settings → Compiler → Java Compiler → Additional command line parameters填-encoding UTF-8或在pom.xml的maven-compiler-plugin里加encodingUTF-8/encoding。4. 系统级根治更彻底可选Windows 设置 → 时间和语言 → 语言和区域 → 管理语言设置 → 更改系统区域设置 → 勾选“Beta: 使用 Unicode UTF-8 提供全球语言支持”→ 重启。这会把整个系统的代码页改成 65001JVM 读到的控制台代码页天然就是 UTF-8sun.stdout.encoding自动变 UTF-8连参数都不用加。少数老软件可能不兼容按需开启。JAVA_TOOL_OPTIONS是在JVM 层解决Beta UTF-8是在操作系统层解决殊途同归。七、总结你以为的实际真相乱码是file.encoding没设 UTF-8JDK 18 默认就是 UTF-8问题不在这加-Dfile.encodingUTF-8就行它管不到System.out的输出流编码IDEA 控制台有 bugIDEA 只是按设定解码锅在上游 JVM 的 stdout 编码一句话根治在JAVA_TOOL_OPTIONS里强制sun.stdout.encoding/sun.stderr.encoding为 UTF-8从输出源头消除 GBK 与 UTF-8 的错配。希望这篇能帮到同样被“只加-Dfile.encoding却没用”坑过的同学。如果对你有用欢迎点赞收藏。