java string在内存中始终以utf-16存储,所谓“设置编码”实为在getbytes()和new string(byte[], charset)转换时显式指定charset;utf-8是推荐通用编码,gbk适用于中文旧系统,iso-8859-1仅作字节搬运不可用于中文编码。

Java 中 String 本身不“带编码”,它在内存中始终以 UTF-16 存储;所谓“设置编码”实际是指:在字符串与字节数组相互转换时,**显式指定字符集(Charset)**,从而控制字节序列的解释或生成方式。关键不是给 String 赋值编码,而是控制 String.getBytes(…) 和 new String(byte[], …) 这两个操作的编码参数。
UTF-8 ↔ String 的标准转换
UTF-8 是最常用、推荐的通用编码。转换安全且可逆:
-
String → UTF-8 字节数组:
str.getBytes(StandardCharsets.UTF_8)或str.getBytes("UTF-8") -
UTF-8 字节数组 → String:
new String(bytes, StandardCharsets.UTF_8) - 中文字符(如“你好”)会转为 3 字节/字,无信息丢失,跨平台兼容性好
GBK ↔ String 的中文场景适配
GBK 主要用于旧系统、Windows 环境或对接国产数据库/文件。注意:GBK 是双字节编码,仅支持简繁体中文及部分符号,不兼容英文以外的多数语言:
-
String → GBK 字节数组:
str.getBytes("GBK")(若含非 GBK 字符会抛UnsupportedEncodingException) -
GBK 字节数组 → String:
new String(bytes, "GBK") - 常见用途:读写本地 GBK 编码的文本文件、连接 legacy MySQL(需 URL 加
&characterEncoding=GBK)
ISO-8859-1 的特殊用途与陷阱
ISO-8859-1 是单字节编码,不能表示中文,但它有个关键特性:256 个码位一一映射字节 0x00–0xFF,因此常被用作“字节搬运工”:
-
误解码修复(典型 Tomcat 场景):前端发 UTF-8 字节,Tomcat 默认用 ISO-8859-1 解码成乱码字符串
s,此时执行new String(s.getBytes("ISO-8859-1"), "UTF-8")可还原 -
不可用于直接编码中文:
"中文".getBytes("ISO-8859-1")会将每个汉字替换成?(即 0x3F),原始字节信息丢失,无法恢复 - 真正安全的用法是:只对已知为 ISO-8859-1 的原始字节流做
new String(bytes, "ISO-8859-1"),而非拿中文去“套”它
避免乱码的核心原则
转码不是“魔法修复”,本质是字节与字符的精确映射。必须确保两步一致:
- 源头字节是什么编码,就用什么编码去解(例如:HTTP 请求体是 UTF-8 字节 → 用 UTF-8 解;GBK 文件 → 用 GBK 解)
-
不要依赖系统默认编码:
str.getBytes()或new String(bytes)无参调用会使用Charset.defaultCharset()(随 OS/IDE 变化),极易出错 -
优先使用
StandardCharsets枚举(如StandardCharsets.UTF_8),类型安全、无异常、性能略优
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











