java中gbk与utf-8转换本质是“字节→unicode→字节”两步过程:先用源编码(如gbk)解码为string(utf-16),再用目标编码(如utf-8)编码为字节;string本身无编码属性,始终为utf-16。

Java 中 GBK 和 UTF-8 的转换,本质不是“字符串转字符串”,而是“字节 ↔ Unicode ↔ 字节”的两步桥梁:先用正确编码把原始字节解码成语义正确的 String(Unicode),再用目标编码把这个 String 编码回字节。String 本身永远是 UTF-16,不带任何编码属性。
怎么确认原始数据是 GBK 还是 UTF-8
不能靠肉眼或内容判断,必须看来源:
- HTTP 响应头含 Content-Type: text/html; charset=gbk 或 charset=utf-8
- 文件保存方式:Windows 记事本选“ANSI”→大概率 GBK;选“UTF-8 无签名”→是 UTF-8
- 数据库连接 URL 含 characterEncoding=gbk 或 characterEncoding=utf8
- 读取文件时若用 Files.readString(path, StandardCharsets.UTF_8) 却出现“?”或“锟斤拷”,说明文件实际是 GBK
GBK 字节数组 → UTF-8 字节数组(正确写法)
前提:你手上的 byte[] gbkBytes 确实是 GBK 编码的(比如从旧系统接口、本地文本文件读取)。
- 用 GBK 解码为 String:new String(gbkBytes, "GBK")
- 再用 UTF-8 编码为新字节:str.getBytes(StandardCharsets.UTF_8)
完整示例:
byte[] gbkBytes = ...; // 真实 GBK 字节 String str = new String(gbkBytes, "GBK"); // 关键:按源编码解码 byte[] utf8Bytes = str.getBytes(StandardCharsets.UTF_8); // 按目标编码编码
UTF-8 字节数组 → GBK 字节数组(对称操作)
逻辑完全一致,只是调换编码名:
- 用 UTF-8 解码:new String(utf8Bytes, StandardCharsets.UTF_8)
- 再用 GBK 编码:str.getBytes("GBK")
注意:不要跳过 String 这一中间层——它承载了正确的 Unicode 语义,跳过会导致乱码放大。
常见错误写法及风险
以下写法看似简洁,但极易出错:
- new String(bytes, "GBK").getBytes("UTF-8"):如果 bytes 实际是 UTF-8,第一步就解错,后续全乱
- new String(bytes).getBytes():依赖系统默认编码(Windows 常为 GBK),跨环境必崩
- 忽略异常:虽然 Java 8+ 内置 UTF-8/GBK,但建议用 StandardCharsets(类型安全、不抛异常)或显式 try-catch
推荐始终使用 StandardCharsets.UTF_8 和 Charset.forName("GBK"),避免字符串硬编码。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











