IDEA 2026.1 EAP 3 修复 Windows 控制台中文乱码:编码链路解析与验证指南
2026/9/8 9:34:37 网站建设 项目流程

早上刷到IntelliJ IDEA 2026.1 EAP 3的 release notes,本来想着这周又把哪个功能打磨得更顺手了,结果翻到中间某一行,直接愣住:

修复:在 Windows 上运行 Java 程序时,如果项目 JVM 使用 UTF-8 编码,控制台不再输出乱码。

就这一行字,夹在几十个修复条目中间,没有加粗、没有配图、没有单独的宣传博客。可你要是从 2019 年开始就在 Windows 上写 Java,看到这句话估计会跟我一样,先愣了一下,然后想给 JetBrains 的工程师鼓个掌。这个问题的相关讨论在 YouTrack 和 Stack Overflow 上已经吵了六年,从"IntelliJ IDEA 控制台中文乱码怎么解决"到"IDEA 2025.3 还是乱码,还有救吗",基本上每隔一阵就会被人翻出来重新问一遍。今天,它终于出现在 EAP 3 的修复列表里。

这篇文章我不会只报一个喜讯就完事。我会把乱码这条链路从头到尾拆一遍,解释为什么这个问题拖了六年才修,EAP 3 大概是怎么修的,以及你升级之后要怎么验证。顺带聊聊这次 EAP 3 里其他几个值得关注的变化,给正在犹豫要不要上 EAP 的同学一个参考。

1. 一个在 Windows 上写 Java 的人都懂的痛

先把这个痛点说得再具体一点。你用 Windows,装了 IDEA,新建一个 Spring Boot 项目或者朴素的 Java 类,写一行System.out.println("中文测试");,点 Run,控制台啪地给你来一堆这玩意:

涓枃娴嬭瘯

或者经典一点的:

锟斤拷锟斤拷锟斤拷

新手看到这基本就懵了,第一反应是自己代码有问题,第二反应是系统有问题,第三反应是翻出各种"万能解决方法"乱试一通。老手则淡定很多,因为他们已经见过太多次了。这些年我和不少同事聊过这个话题,几乎每个在 Windows 上写过 Java 的人都能说出至少一种自己的"止血方案",但没一个人敢说自己彻底搞懂过。

1.1 为什么说"被催了 6 年"不是夸张

这个问题最大的杀伤力在于:它不致命,但极其膈应人。

程序能编译、能运行、逻辑都对,就是打印出来的中文不能看。你要是排查业务障碍,它会浪费你半小时;你要是给新人讲课,它会成为劝退利器;你要是产品上线后看日志,它会让你对临时加打日志这件事充满恐惧。IDEA 里的日志、测试输出、构建输出,任何一个环节出现乱码都够你折腾一阵。

更折磨人的是它的"随机性"。同一个项目,同事的机器上正常,你的机器上乱码;昨天正常,今天更新 JDK 之后开始乱;改了 IDEA 的编码设置好了,重启后又糟。YouTrack 上从 2018 年就开始有人反馈,到 2021 年依旧没修干净,最新一条回复甚至就在上周,下面的 +1 名单长得能翻好几屏。所以说它"被开发者催了 6 年",真不是夸张的说法。

1.2 乱码问题的荒诞之处在于没人说得清

我还发现一个很有意思的现象:你问十个人"IDEA 控制台乱码怎么解决",大概率能得到十种不同的答案。有人说是 IDEA 的编码设置问题,有人说是 JDK 版本问题,有人说是 Windows 区域设置问题,还有人直接让你换电脑。每一种说法都有一定的道理,但又不完全对,这正是乱码问题最折磨人的地方。

这种状态下,任何一个能稳定消灭乱码的版本,都值得单独写一篇,这也是我今天想认真聊聊的原因。

2. 乱码的真正元凶:一条输出链路里的编码错位

要搞清楚 EAP 3 修了什么,得先明白 Windows 上这个乱码是怎么产生的。它本质上不是某一个环节坏了,而是"一段输出从产生到渲染,中间每一步的字符集都不一致"。

2.1 从代码到屏幕,中文到底走了哪几跳

一次简单的System.out.println("中文"),看起来是一瞬间的事,其实要经过四跳:

  1. 源代码文件里的字符串,按照源文件的编码(通常是 UTF-8)保存;
  2. JVM 内部以 UTF-16 存储字符串,调用System.out.println时,把字符串按某种编码转成字节流,写进标准输出管道;这个"某种编码"在 JDK 18 之前默认跟随启动参数-Dfile.encoding,在 JDK 18 之后默认是 UTF-8;
  3. IDEA 的 ProcessHandler 从子进程的 stdout 管道里读到一堆字节;
  4. IDEA 控制台组件用一个字符集把这堆字节解码成字符串,然后渲染到界面上。

只要第 2 步和第 4 步用的字符集不一致,显示出来就是乱码。

Windows 中文系统默认的区域设置是简体中文(代码页 936),旧版 JDK 在没有显式指定file.encoding时,System.out会跟着系统走,用 GBK 输出字节。老版本 IDEA 在 Windows 上解码控制台输出时,也优先用系统默认字符集,也就是 GBK。两层都是 GBK,反而歪打正着,不乱码。

但后来的故事大家也知道了:JDK 18 开始,JEP 400 把file.encoding的默认值从"跟随系统"改成了 UTF-8。也就是说,Java 程序现在默认按 UTF-8 往外倒字节。而 IDEA 那边呢,很长一段时间在 Windows 上依然默认按 GBK 去解控制台的字节流。一个用 UTF-8 写,一个用 GBK 读,于是那些经典的"锟斤拷"就大规模出现了。

2.2 JDK 18 只是催化剂,旧账早就欠下了

有人可能会问:那 JDK 18 之前不乱码吗?也不是。JDK 18 之前,IDEA 自己的构建日志、Maven 输出、某些第三方工具输出,因为各自继承的字符集不一样,照样经常乱。JDK 18 的出现只是把这个矛盾集中引爆了:程序自己按 UTF-8 输出,IDEA 控制台却按 GBK 解码,乱码从"偶发"变成"必现"。

还有一个容易被人忽视的点:System.out的实际输出字符集,并不是由file.encoding一个属性决定的。JDK 里至少有三个相关的系统属性容易搞混:

  • file.encoding:JVM 处理文件 I/O 时默认使用的编码;
  • stdout.encoding:标准输出流的实际编码,受是否重定向、控制台类型影响;
  • sun.jnu.encoding:JVM 与操作系统交互时用的编码,比如解析命令行参数、文件系统路径。

我见过很多项目的"土办法"只加了-Dfile.encoding=UTF-8,结果发现控制台还是乱,就是因为 stdout 的实际编码可能走的是另一套逻辑。后面我会专门写一段怎么用命令把这几个值打出来看。

2.3 IDEA 为什么不能直接猜中编码

你可能会想:IDEA 不是恶心了六年吗?直接默认按 UTF-8 解码不就行了?问题是,IDEA 控制台要伺候的不只是 Java 程序的 stdout,还有 Maven 输出、Gradle 输出、脚本输出、外部进程输出,这些进程的输出编码五花八门,有的甚至不是 UTF-8 也不是 GBK。

更要命的是,IDEA 在大多数场景下只是"读字节"的一方,它拿不到子进程在运行时真正的编码。即使拿到了启动参数,子进程也可以在执行中途改变System.out的 PrintStream 包装。让 IDE 用一个固定的编码去解所有的流,必然会顾此失彼。这也是为什么 JetBrains 从前一直把这个改动往下压,因为它不是一个"拍脑袋改成 UTF-8"就能交差的事,而是需要一套相对完整的编码识别策略。

下表能帮你快速理解不同组合下的表现:

程序输出编码IDEA 控制台解码显示结果
GBKGBK正常
UTF-8UTF-8正常
UTF-8GBK中文乱码(经典锟斤拷)
GBKUTF-8中文乱码(???或方框)

这次 EAP 3 的修复,核心思路就是把这套"猜编码"的逻辑做得更聪明一些,而不是无脑修改默认值。具体我放到第 4 节讲。

3. 这些年我们用的"土办法",和它们的问题

在讨论 EAP 3 的修复细节之前,我想认真盘点一下过去六年里中文开发者圈子里流传最广的几种"土办法"。原因很简单:这些方法现在仍然能在各种技术博客里看到,如果你不理解它们的副作用,升级到 EAP 3 之后可能还会继续被它们误导。

3.1 流传最广的三招

第一招:改 IDEA 的idea64.exe.vmoptions,加一行-Dfile.encoding=UTF-8

这个方法能影响 IDEA 进程本身的编码,但对子进程(你运行的那个 Java 程序)的影响是间接的。如果你的程序是通过 Maven/Gradle 启动的,最终生效的可能是构建工具自己的 JVM,而不是 IDE 的 JVM。改了之后,IDE 自身的进度条、日志、控制台框架部分可能变正常,但程序里的 println 该乱还是乱。

第二招:在 Run/Debug Configuration 的 VM options 里加-Dfile.encoding=UTF-8

这让被启动的那个 JVM 默认按 UTF-8 处理文件 I/O。JDK 18 之后这步很多时候是多余的,因为默认已经是 UTF-8。但在某些旧版 JDK 或经过特殊配置的构建工具里,这招仍然有效。副作用是:如果你在同一个配置里既跑测试又跑应用,测试框架 fork 出的子进程不一定继承这个参数。

第三招:在系统环境变量里设置JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8

全局生效,所有 Java 进程都会被注入,但每次启动 Java 程序时 JVM 都会往 stderr 打一行 "Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8",日志脚本里多出一行莫名其妙的输出不说,如果哪天你部署到服务器忘了清理这个变量,线上程序的行为都会被改变。

我把它们归纳成一张表:

方法生效范围副作用能否根治
改 vmoptionsIDEA 进程子进程感知不稳定不能
改运行配置 VM options单个启动 JVM测试 fork 不继承不能
设 JAVA_TOOL_OPTIONS所有 Java 进程全局污染,服务器易受影响不能

3.2 为什么这些方法都没治好根

这些土办法的思路都是"把某一端的编码改成 UTF-8",但乱码的本质是两端不一致,以及中间还有构建工具、测试框架可能 fork 出新的进程。你只改了其中一端,另一端还在按 GBK 解码,乱码自然还会复发。

更坑的是,很多文章把这几招揉在一起教人:先改 vmoptions,再改环境变量,最后再把 Project Encoding 改成 UTF-8,一顿操作猛如虎,结果是"不知道是哪一步起了作用,也不敢乱动"。一旦换台电脑、换个人,问题马上就回来。

3.3 一个命令看清当前环境的真实编码

不管用不用土办法,我建议你在折腾之前,先跑一段小代码,确认当前环境的真实状态:

public class EncodingCheck { public static void main(String[] args) { System.out.println("file.encoding = " + System.getProperty("file.encoding")); System.out.println("stdout.encoding = " + System.getProperty("stdout.encoding")); System.out.println("sun.jnu.encoding= " + System.getProperty("sun.jnu.encoding")); System.out.println("native.encoding = " + System.getProperty("native.encoding")); System.out.println("中文乱码测试:正常就说明链路一致"); } }

在 IDEA 里直接运行,观察控制台:

  • 如果你看到file.encoding=UTF-8,说明 JVM 默认文件编码是新版 JDK 的标准配置;
  • 如果你看到stdout.encoding=UTF-8,但是控制台依然乱码,说明解码端(IDEA 控制台)还在用 GBK;
  • 如果你看到sun.jnu.encoding=GBK,说明 JVM 和 Windows 系统交互那一层还是 GBK,这层主要影响命令行参数和文件路径,一般不用动。

这个命令在你升级到 EAP 3 之后同样有用,可以用来判断修复是否真的生效。

4. 2026.1 EAP 3 这次是动了真格

好,聊完背景,我们来看看 EAP 3 的这次修复。

4.1 控制台不再"盲猜":先读启动参数,再决定解码字符集

这次修复的核心,我认为是 IDEA 在启动一个 Java 子进程的时候,会从运行配置和 JVM 参数里提取出与编码相关的信息,组合成一组"解码规则",再用这组规则去解析 stdout 的字节流。

说得更直白一些:以前 IDEA 控制台是"打开一个管道,拿系统默认字符集硬解";现在它会在读取之前先看一眼这个子进程到底是怎么起来的。如果你的运行配置里没有显式指定file.encoding,检测到 JDK 18+,那就按 UTF-8 解;如果你在 VM options 里写了-Dfile.encoding=GBK,那别的参数再花里胡哨,也按 GBK 解。

这个思路并没什么黑科技,但对 IDEA 来说意义重大。因为它意味着"默认按系统代码页解码"这个 Windows 上的历史包袱,终于被放下了。Windows 中文系统控制台里跑 Java 程序,默认 UTF-8 输出,IDEA 控制台默认 UTF-8 解码,链路从头到尾一致,乱码自然消失。

4.2 Maven/Gradle 的构建输出也接上了同一套逻辑

乱码不只发生在Run窗口,Maven 的依赖下载日志、Gradle 的 Task 输出、测试报告里的中文,过去同样是重灾区。EAP 3 这次把构建工具的 ProcessHandler 也接入了编码识别逻辑。

比如 Maven 在 Windows 下通过mvn命令启动的 Java 进程,输出编码通常继承自 Maven 自身的 JVM;而 Maven 又经常 fork 出新的 JVM 跑测试,这个进程的输出编码又可能单独受 surefire 配置影响。EAP 3 会沿着这条链逐级读取关键配置,尽量在每一级都用对的字符集去解码。

不过我要提醒一句:构建工具 fork 出来的进程,配置来源非常复杂,EAP 3 的自动识别大概率覆盖不了所有情况。如果你遇到"Run 窗口正常了,Gradle 测试输出还是乱"这种残留情况,请先别急着抱怨,继续看下一节的手动兜底方案。

4.3 手动兜底:控制台输出编码设置

JetBrains 自己也清楚,自动识别做不到 100% 准确,尤其是遇到各种自定义脚本、外部工具的 stdio 输出时。所以 EAP 3 里我注意到一个配套设置被保留和强化了:在 Settings 里搜索 "Console Encoding" 或者"控制台编码",可以手动指定控制台默认的字符集。

大概位置应该是在Settings > Build, Execution, Deployment > Console之下。你可以选择:

  • Use system default(默认,现在 EAP 3 下运行 Java 程序实际会走 UTF-8 识别逻辑);
  • UTF-8
  • GBK
  • 其他编码。

这个设置是给那些"程序确实在输出 GBK 字节"的老项目准备的。如果你维护的是一个历史项目,代码文件是 GBK,打包脚本也是 GBK,那你在保证文件编码也一致的前提下,把手动编码设成 GBK,反而能让控制台继续正常。

4.4 修复边界:不是所有控制台都是同一个控制台

这一点特别容易造成误解。IDEA 里的"输出区域"分成好几类:

  • Run/Debug 窗口(运行程序的 stdout/stderr);
  • Build 窗口(构建工具输出);
  • Services 窗口(Spring Boot / Docker 等服务输出);
  • Terminal(真正的终端模拟器,不进 ProcessHandler 这套体系)。

EAP 3 的乱码修复主要覆盖前两类和大部分服务输出,Terminal 窗口因为本质是终端模拟器,它的编码行为由 shell 本身的代码页决定,和 IDEA 的 ProcessHandler 不是一条技术路线。如果你在 Terminal 里敲java -version都乱码,那是 Windows 终端层的老问题,不要用"IDEA 控制台乱码"的思路去排查。

5. 升级到 EAP 3,并亲手验证这个修复

既然说到了 EAP 3,那我再花点篇幅讲讲怎么安全地尝鲜,以及如何验证这个乱码修复在你机器上确实生效。

5.1 升级姿势:Toolbox 安装,和稳定版共存

我强烈建议用 JetBrains Toolbox 来安装 EAP 版本,而不是直接卸载正式版去换 EAP。

用 Toolbox 的时候,IDEA 2026.1 EAP 3 会单独装一份,配置文件目录也是独立的(通常是%APPDATA%\JetBrains\IntelliJIdea2026.1),不会覆盖你稳定版的IntelliJIdea202x.x配置。这样你可以一边用稳定版干活,一边用 EAP 验证修复,两边互不干扰。

注意 EAP 默认会把稳定版装过的一些插件也复制过去,但因为 EAP 的兼容性标记更严格,部分插件可能显示为"不兼容"。插件不多的话,建议全新安装 EAP 后只按需启用插件,不要在 EAP 里跑你最重要的生产环境依赖链。

5.2 迁移配置的正确姿势

如果你想保留稳定版的主题、快捷键、代码风格,不要直接去拷idea.propertiesoptions目录。正确做法是:

  1. 在稳定版里执行File > Manage IDE Settings > Export Settings,导出一个 zip;
  2. 在 EAP 3 里执行File > Manage IDE Settings > Import Settings,导入该 zip;
  3. 导入后重启 EAP,检查 Keymap、Editor > Font 等关键项是否正常。

这个流程比手动拷配置文件安全很多,能避免因为 EAP 配置格式变化导致的一堆奇怪问题。

5.3 分步验证:从 Run 窗口到 Maven 输出

装好之后,用下面这套步骤验证乱码修复。先说前提:操作系统是 Windows 中文版或区域设置为中文,不要为了测试而去改系统 UTF-8 测试版,我们要验证的是 IDEA 侧的能力。

第一步,新建一个 Java 项目,JDK 选 21 或更高版本,项目编码保持默认(UTF-8)。

第二步,在src下写一个类:

public class EncTest { public static void main(String[] args) { System.out.println("中文测试"); System.out.println("锟斤拷是一种精神污染"); System.err.println("错误输出里的中文也要正常"); } }

第三步,直接点 Run。预期结果是:EAP 3 里控制台这三行中文全部正常显示,不会出现涓枃锟斤拷

第四步,验证 Maven/Gradle 输出。在项目里加一个简单的 Maven 插件,打印一条中文日志:

<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>3.2.0</version> <configuration> <executable>java</executable> <arguments> <argument>-classpath</argument> <classpath/> <argument>EncTest</argument> </arguments> </configuration> </plugin>

也可以在 pom 里加maven-antrun-plugin输出中文。重点看 Build 窗口里这条中文日志是否正常。

第五步,如果你手头有老项目是非 UTF-8 的,可以单独建一个 Run Configuration,在 VM options 里写-Dfile.encoding=GBK,再跑一个输出中文的程序。这时候 EAP 3 应该能根据这个显式参数,自动用 GBK 去解码,而不是死板地按 UTF-8 解。

5.4 万一还是乱,按这个清单排查

  • 确认你打开的是 2026.1 EAP 3 的进程,而不是电脑里残留的旧版本(Toolbox 装多了容易点错);
  • 确认项目文件编码与file.encoding一致,源文件如果是 GBK,你 IDE 默认 UTF-8,那打出来的字符串本身就是错的,这不属于控制台解码问题;
  • 检查控制台编码设置是否被手动改成了 GBK,改回Use system default
  • 检查是否设置了JAVA_TOOL_OPTIONS之类的环境变量,有就先清掉再试;
  • 如果跑的是 Maven 测试 fork 出来的进程,去看 surefire 的<argLine>配置,确认没有强制指定奇怪的编码。

这几条能过滤掉 90% 的"升级完还乱"的情况。

6. EAP 3 里其他让我觉得不是白等的变化

乱码修复是这次 EAP 3 最吸引我的一点,但它不是全部。简单盘点几个我这周试用下来觉得也值得关注的变化。

6.1 新版终端更接近转正状态

2025 年开始 JetBrains 就在推新版终端,EAP 3 里它已经是默认开启的状态,至少在 Windows 上我试了 PowerShell 和 Git Bash,启动速度和补全响应都比旧终端好不少,也没有之前那种一操作就崩的挫败感。以前习惯在外部终端里做 git 操作的同学,可以再给新版终端一次机会。

6.2 Kafka 内置支持的功能更完整了

如果你是做消息队列开发的人,应该很早就关注到 IDEA 对 Kafka 的内置支持。EAP 3 版本里,主题浏览、分区 offset 查看、消息内容格式化这些功能都更完善了,连接配置错误的提示也比之前友好。以前要装第三方插件才能完成的消息模拟发送,现在在 Service 工具窗口里就能直接做。虽然我对这个功能的需求不是天天有,但每次要用的时候,发现 IDE 里就带着,体验确实比装插件稳定。

6.3 Kotlin 调试信息的内联提示更克制了

调试 Kotlin 协程时,变量视图以前经常一长串 internal 字段挤在一起,EAP 3 对这类内联提示做了收敛,只展示业务相关的关键信息。对 Kotlin 开发者来说,这个细节比想象中影响大,调试体验清爽了不少。

6.4 项目索引与首屏加载还在继续加速

2025 年的几个大版本一直在改项目模型,EAP 3 给我的体感是:首次打开大型 Maven 项目,索引过程中 IDE 卡顿的次数明显少了;之前的 "Reading external files" 阶段耗时也缩短了。对一个动辄几十个模块的企业项目来说,这个改进比很多花哨的新功能更实在。

6.5 新 UI 的小细节终于不跟我较劲了

还有一个很主观的感受:EAP 3 的新 UI 在细节上终于不再跟我的操作习惯较劲了。工具窗口的折叠动画更干脆,标签页拖拽的响应速度更快,右侧滚动条里的代码问题提示也更清晰了。以前我属于那种"为了稳定坚决留在旧 UI"的人,这次试了几天新 UI,居然没有切回去的冲动。这算是一个信号:JetBrains 终于把新 UI 的完成度拉到了"可以默认"的水平。

7. 我的一点个人体会

作为一个在 Windows 上写了快十年 Java 的人,我太清楚控制台乱码在这种"不算 bug 但又天天烦你"的问题上有多消耗人。每次看到群里有人问"IDEA 控制台中文乱码怎么办",我都能脑补出屏幕对面的开发者有多无奈。所以这次 EAP 3 的修复,对我来说不只是一个新版本的发布说明,更像是一件挂了六年的心事终于有了着落。

不过我还是要泼一盆理性的冷水:EAP 3 解决了 IDEA 控制台解码这一侧的默认值问题,但编码一致性是一个系统工程。项目的源文件编码、构建工具的 fork 参数、日志框架的编码设置、部署环境的字符集变量,这些环节依然可能各自为政。建议大家在庆祝完控制台不乱码之后,顺手检查一下自己项目的编码配置:

  • 每个模块的.idea/encodings.xml是否统一;
  • Maven 的project.build.sourceEncoding是否显式声明;
  • 日志文件和 JDBC 连接串里的characterEncoding是否一致。

最后分享一个我踩过很多次才记住的经验:file.encoding管的是 JVM 内部文件读写,stdout.encoding管的是控制台输出,sun.jnu.encoding管的是系统交互层。三者的默认值在新版 JDK 里都趋向 UTF-8,但你一旦开始手动指定,它们是可以互相掉队的。排查乱码的时候,不要再只盯file.encoding一个属性了,把第 3 节那段代码跑一遍,你会省下很多无谓的尝试。

至于要不要现在升级 EAP,我的建议是:如果你只是一个普通业务开发者,可以等 2026.1 正式版,没必要在 EAP 上折腾;但如果你长期被 Windows 控制台乱码困扰,或者对 Kafka 内置支持、新版终端这些功能感兴趣,那 EAP 3 完全值得用 Toolbox 装一份来体验。我的乱码验证已经通过了,希望你这个版本也能告别"锟斤拷"。

愿你这辈子写代码,看到的都是能看懂的字。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询