Java字符串乱码核心在于编码与解码未使用同一字符集,如UTF-8字节被GBK误读;必须显式指定UTF-8等统一编码,禁用依赖系统默认值的无参方法,并在文件、网络、数据库及Web各层协同规范编码设置。

Java中处理字符串乱码,核心是确保“编码”和“解码”两端使用**同一字符集**。乱码不是字符串本身坏了,而是字节被用错了规则去解释——比如把UTF-8存的字节当GBK去读,自然显示成问号或方块。
明确指定字符编码,不依赖默认值
Java运行时会读取系统默认字符集(如Windows是GBK,Linux/macOS通常是UTF-8),但这个值不可控、不跨平台。只要涉及外部数据(文件、网络、数据库),就必须显式传入编码名,不能省略。
- 写字符串到文件:用 OutputStreamWriter(new FileOutputStream(f), "UTF-8")
- 读文件内容:用 InputStreamReader(new FileInputStream(f), "UTF-8")
- 构造字符串:new String(bytes, "UTF-8")(避免无参构造函数)
- 获取字节数组:str.getBytes("UTF-8")(避免无参getBytes())
统一项目级编码规范
从源头避免不一致,需要多层协同:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
- 源文件(.java):在IDE中设为UTF-8(IntelliJ IDEA → File → Settings → Editor → File Encodings;Eclipse → Preferences → General → Workspace → Text file encoding)
-
编译过程:命令行编译加参数 javac -encoding UTF-8 *.java;Maven项目在pom.xml中配置maven-compiler-plugin的
<encoding>UTF-8</encoding> - 控制台输出:Windows cmd中执行 chcp 65001 切换为UTF-8;IDE运行配置里添加VM选项 -Dfile.encoding=UTF-8
Web场景下重点管控HTTP交互
浏览器与服务器之间极易因缺失charset声明而退化为ISO-8859-1,导致中文参数全乱:
立即学习“Java免费学习笔记(深入)”;
- 请求参数:Servlet中调用 request.setCharacterEncoding("UTF-8")(需在读取参数前调用,如getParameter之前)
- 响应输出:设置响应头 response.setContentType("text/html; charset=UTF-8") 或 response.setCharacterEncoding("UTF-8")
- JSP页面顶部加:
- 表单提交时,HTML中指定: 和 form accept-charset="UTF-8"
排查与验证技巧
遇到乱码别猜,用字节说话:
- 打印原始字节:对疑似乱码字符串调用 str.getBytes(StandardCharsets.UTF_8) 和 str.getBytes(StandardCharsets.ISO_8859_1),对比十六进制结果,能反推它原本是按什么编码生成的
- 检查文件真实编码:用Notepad++或VS Code打开文件,右下角查看实际编码;不要只信扩展名或编辑器默认识别
- 数据库连接串加参数:MySQL JDBC URL末尾加上 ?useUnicode=true&characterEncoding=UTF-8
- 日志输出加编码标识:在关键日志中同时打印字符串长度、字节数组长度及前几个字节,便于定位阶段

















