Java中String.getBytes()默认使用平台字符集(如Windows为GBK、Linux/macOS为UTF-8),易致跨平台乱码;必须显式指定统一字符集(如StandardCharsets.UTF_8)并配对用于编码与解码,才能彻底避免乱码。

在 Java 中,String.getBytes() 默认使用平台默认字符集(如 Windows 是 GBK,Linux/macOS 通常是 UTF-8),这会导致跨平台传输时字节数组解码不一致,出现乱码。要彻底避免这个问题,必须**显式传入标准字符集名称或 Charset 对象**,而非依赖默认行为。
明确指定字符集名称(推荐用标准字符串)
直接传入标准字符集名称字符串,例如 "UTF-8"、"ISO-8859-1" 或 "GBK"。Java 会自动查找对应 Charset 实例,简洁且兼容性好。
- ✅ 正确写法:
byte[] data = str.getBytes("UTF-8"); - ⚠️ 避免写法:
str.getBytes()(平台相关,不可控) - ⚠️ 不推荐写法:
str.getBytes("utf8")或"Utf-8"(大小写敏感,非标准名可能抛UnsupportedEncodingException)
优先使用 Charset 常量(类型安全,无异常风险)
从 Java 7 起,StandardCharsets 提供了预定义的静态 Charset 实例,调用 String.getBytes(Charset) 不会抛出检查异常,更健壮。
- ✅ 推荐写法:
byte[] data = str.getBytes(StandardCharsets.UTF_8); - ✅ 同样安全:
str.getBytes(StandardCharsets.ISO_8859_1) - ❌ 不要用
Charset.forName("UTF-8")包装——多此一举,还可能抛异常
发送与接收两端必须约定统一字符集
仅编码端指定不够,解码端也必须用**完全相同的字符集**还原字符串,否则仍会乱码。常见场景如下:
立即学习“Java免费学习笔记(深入)”;
- 网络传输(如 HTTP POST):客户端用
UTF-8编码,服务端也必须用UTF-8解码 - 文件读写:写入时
str.getBytes(UTF_8),读取后用new String(bytes, UTF_8) - 数据库存取:确认 JDBC 连接 URL 和字段字符集(如
useUnicode=true&characterEncoding=UTF-8)
调试乱码问题的小技巧
当遇到疑似乱码时,快速验证字节内容是否符合预期:
- 打印编码后的字节(前 10 个):
System.out.println(Arrays.toString(str.getBytes(UTF_8))); - 对比两端实际使用的字符集:
System.out.println(Charset.defaultCharset());(仅用于排查,默认值不应参与逻辑) - 用
new String(bytes, "ISO-8859-1")查看原始字节可读形式(适合分析二进制污染)
只要编码和解码使用同一个标准字符集,比如全程用 StandardCharsets.UTF_8,跨平台乱码问题就能根本解决。不复杂但容易忽略。


















