
IDEA 里 file.encoding 和 console.encoding 必须一致
Java 源文件读取、编译、运行时控制台输出,三者编码不统一是乱码最常见原因。IntelliJ IDEA 默认可能用系统编码(比如 Windows 的 GBK),但项目源码是 UTF-8,结果编译时字面量被错误解码,运行时又用 GBK 解 console 输出——中文直接变 ??? 或方块。
- 进
File → Settings → Editor → File Encodings,把Global Encoding、Project Encoding、Default encoding for properties files全设成UTF-8 - 关键一步:点右下角齿轮图标 →
Configure → Configure IDE Encoding,勾选Override default encoding for console,并设为UTF-8 - 如果用了 Maven,还要在
pom.xml中显式指定编译编码:<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties>
javac 命令行编译必须加 -encoding UTF-8
不用 IDE 直接敲 javac?默认会按系统 locale 解码源码。Windows 上跑 javac Main.java,哪怕文件存的是 UTF-8,也会被当成 GBK 解析,中文字符串字面量直接报错 illegal character: '\uFFFD' 或编译后输出乱码。
- 永远显式带上参数:
javac -encoding UTF-8 Main.java - 如果写成脚本或 Makefile,别漏掉这个参数;CI 环境(如 GitHub Actions)更要注意,默认 runner 是英文 locale,没指定就容易翻车
-
java运行时一般不需要额外参数(JVM 读 class 字节码,不涉及源码编码),但若用java -Dfile.encoding=GBK强制改了,反而可能让new String(bytes)出问题
读写文件时别依赖平台默认编码,显式传 StandardCharsets.UTF_8
new FileInputStream("a.txt") 配 new Scanner(inputStream),或者 Files.readAllLines(path),这些 API 底层都偷偷用 Charset.defaultCharset()——它由 JVM 启动时系统环境决定,不可控。同一份代码,在 macOS 和 Windows 上行为不同是常态。
- 用
Files.readAllLines(path, StandardCharsets.UTF_8)替代无参版本 -
Scanner构造时传编码:new Scanner(new FileInputStream("a.txt"), StandardCharsets.UTF_8) - 写文件同理:
Files.write(path, lines, StandardCharsets.UTF_8),别用PrintWriter无参构造 - 注意
String.getBytes():它也依赖默认编码,应写作str.getBytes(StandardCharsets.UTF_8)
Spring Boot / Tomcat 启动时 HTTP 请求体和响应体的编码
Web 场景下,前端 POST 提交中文,后端 @RequestBody 接到乱码;或返回 JSON 里中文变成 \u4f60\u597d 或直接问号——这和源码编码无关,是 HTTP 层的字符集协商问题。
立即学习“Java免费学习笔记(深入)”;
- Spring Boot 2.3+ 默认已设
server.servlet.encoding.charset=UTF-8和server.servlet.encoding.force=true,但老版本或自定义TomcatServletWebServerFactory时得手动配 - 确保请求头带
Content-Type: application/json;charset=UTF-8,否则 Spring 可能按 ISO-8859-1 解 body - 响应头要含
Content-Type: application/json;charset=UTF-8,可通过@RequestMapping(produces = "application/json;charset=UTF-8")或全局配置spring.http.encoding.force=true(旧版) - 别信“浏览器自动识别”,Chrome 对无 charset 的响应一律当 ISO-8859-1 处理
-encoding;写了 StandardCharsets.UTF_8,HTTP 层又漏配;甚至 Git 提交时换行符和编码混在一起,拉下来就变样。最容易忽略的是:你以为改了某一处,其实有三处地方在各自悄悄用不同编码干活。











