standardcharsets 是 jdk 7+ 提供的预定义 charset 常量类,含 utf_8、us_ascii 等线程安全静态实例;相比字符串编码名(如 "utf-8"),它支持编译期校验、零运行时开销、ide 可导航,且避免 unsupportedencodingexception 和大小写/拼写错误风险。

StandardCharsets 是啥,为什么不能自己 new String(bytes, "UTF-8")
它是一组预定义的 Charset 实例,不是工具类也不是枚举,而是 final 类里一堆 static final 的常量。用它比传字符串编码名更安全:编译期就校验编码是否存在,避免运行时抛 UnsupportedEncodingException。
常见错误是写成 new String(bytes, "GBK") 或 str.getBytes("UTF-8") —— 这些字符串字面量拼错、JVM 不支持该编码时才会报错,而 StandardCharsets.UTF_8 是 IDE 可跳转、编译器可检查的。
- 所有常量都是线程安全的,可直接静态引用,无需缓存或单例包装
- Android 4.4+ 才完整支持全部常量(如
StandardCharsets.ISO_8859_1),低版本需降级处理 - 不推荐用
StandardCharsets.UTF_16,它没指定 BOM 和大小端,实际应选StandardCharsets.UTF_16BE或StandardCharsets.UTF_16LE
UTF_8 / US_ASCII / ISO_8859_1 这三个最常用常量的区别和场景
别只记名字,得看它们能干啥、不能干啥:
-
StandardCharsets.UTF_8:通用首选,兼容 ASCII,能表示所有 Unicode 字符;但注意:某些旧协议(如 SMTP 头)要求 ASCII 子集,此时不能直接塞 UTF-8 字节 -
StandardCharsets.US_ASCII:严格 0x00–0x7F,超范围字符会静默替换为?(在String.getBytes(US_ASCII)时);适合协议头、文件名安全化等必须纯 ASCII 的场合 -
StandardCharsets.ISO_8859_1:单字节编码,0x00–0xFF 映射到 Unicode 码点 0x0000–0x00FF;常被误用作“万能解码兜底”,其实它对中文等完全无效——只是把每个字节当 Latin-1 字符显示成乱码
示例:读取 HTTP 响应头中的 Content-Type,规范要求是 ASCII,用 US_ASCII 解码最稳妥;而解析响应体正文,优先用 UTF_8,fallback 再考虑服务器声明的 charset。
立即学习“Java免费学习笔记(深入)”;
和 Charset.forName() 混用会出什么问题
有人图省事,把 StandardCharsets.UTF_8 和 Charset.forName("UTF-8") 当成等价物混用,但它们有本质差异:
-
StandardCharsets.UTF_8是单例对象,每次获取都返回同一个实例,== 比较成立;Charset.forName("UTF-8")在某些 JDK 版本中可能返回新实例,== 判断会失败 -
Charset.forName()每次调用都查表+反射,有轻微开销;StandardCharsets常量是编译期绑定,零成本 - 如果代码里同时存在两种写法(比如一个地方用
StandardCharsets.UTF_8,另一个地方用Charset.forName("utf8")),小写的"utf8"在部分 JVM 上不识别,会抛异常
所以只要 JDK 7+,一律用 StandardCharsets 常量;只有在动态加载用户配置的编码名(比如从 XML 读 <encoding>GBK</encoding>)时,才必须用 Charset.forName()。
序列化/网络传输中忽略 charset 的典型坑
很多开发者以为 “反正我用的是 UTF-8”,就省略显式指定 charset,结果在跨环境时出问题:
-
PrintWriter构造时不传StandardCharsets.UTF_8,默认用平台编码(Windows 是 GBK,Linux 是 UTF-8),日志文件一换机器就乱码 -
Files.write(path, lines, StandardCharsets.UTF_8)忘了第三个参数,写出来是系统默认编码,CI 机器上可能和本地不一致 - HTTP 客户端(如 OkHttp)发 JSON 时没设
Content-Type: application/json; charset=utf-8,服务端可能按 ISO-8859-1 解析中文字段
真正麻烦的不是写错,而是错得不报错——字节写进去了,人眼看着像“差不多”,直到某天导出 Excel 或对接第三方系统才暴露。










