Java项目必须统一显式设置UTF-8编码:源文件存为UTF-8无BOM;编译阶段用-javac -encoding UTF-8、Maven配project.build.sourceEncoding、Gradle设compileJava.options.encoding;运行时加-Dfile.encoding=UTF-8;IDE同步全局/项目/properties编码;IO与网络操作须显式指定StandardCharsets.UTF_8。

Java 中并没有官方发布的《字符编码规范手册》,但可以通过整理 JDK 文档、Java 语言规范(JLS)、Java 虚拟机规范(JVMS)以及实际开发中的最佳实践,编写一份实用、可落地的内部字符编码规范指南。核心目标是统一源码、编译、运行、I/O、网络传输等环节的编码处理逻辑,避免乱码、数据截断或安全问题。
明确源文件编码:统一使用 UTF-8
Java 源文件(.java)默认按平台编码读取,但跨平台协作时极易出错。必须强制约定:
- 所有 .java 文件保存为 UTF-8 编码(无 BOM);
- 在 IDE(如 IntelliJ IDEA、Eclipse)中全局设置「File Encoding」为 UTF-8,并勾选「Transparent native-to-ascii conversion」(避免中文字符串被自动转义);
- 通过 javac -encoding UTF-8 显式指定编译编码,禁止依赖系统默认;
- Maven 项目需在 pom.xml 中配置:
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
字符串与字节转换:显式指定 charset,禁用平台默认
Java 的 String.getBytes() 和 new String(byte[]) 默认使用系统 default charset,这是生产环境乱码的头号来源。
- 永远传入 charset 名称,例如:
str.getBytes(StandardCharsets.UTF_8)或new String(bytes, StandardCharsets.UTF_8); - 禁止使用
getBytes()、new String(bytes)这类无参重载; - 在日志、调试、序列化场景中,若需字节表示,优先记录 charset 名称(如 "UTF-8"),而非仅存 raw bytes;
- 使用 StandardCharsets(JDK 7+)代替字符串字面量(如 "UTF-8"),避免拼写错误和类加载异常。
IO 与网络:流操作必须绑定 charset
文件读写、HTTP 请求/响应、数据库连接等 I/O 场景,charset 必须显式声明,不可隐式推导。
立即学习“Java免费学习笔记(深入)”;
- 文本文件读写:用 InputStreamReader/OutputStreamWriter 包装流,并传入
StandardCharsets.UTF_8; - 推荐使用 NIO.2:
Files.readAllLines(path, UTF_8)、Files.write(path, lines, UTF_8); - HTTP 客户端(如 HttpURLConnection、OkHttp、RestTemplate):设置
Content-Type: text/plain; charset=UTF-8,并确保请求体/响应体解析时指定 charset; - JDBC 连接 URL 中添加
useUnicode=true&characterEncoding=UTF-8(MySQL)或对应数据库的编码参数。
运行时与环境:标准化 JVM 启动参数
虽然 Java 内部 String 始终是 UTF-16,但部分底层操作(如 System.console()、本地文件系统路径、JNI)仍受系统 locale 影响。
- 生产环境启动脚本中统一添加 JVM 参数:
-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8; - 容器化部署(Docker)中,基础镜像应设置环境变量:
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8; - 避免依赖
Charset.defaultCharset()—— 它返回的是 JVM 启动时推断的值,不可控; - 在关键入口(如 Spring Boot 的
@PostConstruct)可做一次校验:打印Charset.defaultCharset()并告警非 UTF-8 场景。
不复杂但容易忽略:规范的生命力在于可检查、可执行。建议配套提供 Checkstyle 规则(拦截无参 getBytes)、单元测试模板(验证含中文路径/参数的 IO 行为)、以及 CI 流水线中的编码扫描步骤(如用 SonarQube 检测硬编码 charset 字符串)。


















