Java字符编码总结

Java 开发过程中,或多或少都会遇到乱码问题,常见的场景是,本地运行调试都很正常,一但上生产就乱码。有经验的开发者,马上会意识到是因为系统编码不一致导致的。这时,如果程序中通信或处理的编码格式有好几种,而开发者对Java处理编码的原理又不够了解,往往会被弄的焦头烂额。

String

先看下简单的 String 声明:

1
String str = "字符串"

问:这段代码声明的字符串是什么编码的?
答:可能是 GBK,也可能是 UTF-8,也可能是 UTF-16,甚至是其他已知的任何编码。

没错, 一般在 Windwos 下,它是 GBK,MAC 下他又会变成 UTF-8,Linux 有时 GBK 有时 UTF-8。为什么呢?

其实原理很简单,Java 字符串的默认编码 == 系统环境的字符编码,也就是说,如果你的系统是 GBK ,那么 Java 中的所有 String 默认就都是 GBK。

转码

那么,如何转码呢?假设需求是一定要将上面的 String 转成 UTF-8,要怎么做? 看代码:

1
2
String gbkStr = "字符串";    // 假设系统默认是 GBK
String utf8Str = new String(gbkStr.getBytes("UTF-8"), "UTF-8"); // 得到 utf-8 的 String

这里要着重注意一下 getBytes 方法。
getBytes 的作用是将一个字符串转换为指定编码的 byte 数组,当不携带编码参数时,默认为系统编码,即:

String.getBytes() 得到一个系统默认的编码格式的字节数组。 Windows 就是 GBK。
String.getBytes("UTF-8") 得到一个UTF-8格式的字节数组。

再看 new String,它的作用是将 byte 数组转换为对应编码的字符串。

串联起来再看代码,首先是通过 String.gebytes(“UTF-8”) 得到一个 UTF-8 格式的 byte 数组,再通过 new String 指定编码格式,得到一个 UTF-8 格式的字符串。

也就是说真正的转码在于 getBytes(“UTF-8”),new String 只不过是生成字符串。

场景举例

理解上面的原理后,基本上就可以很从容的面对 Java 开发中遇到的大部分编码乱码问题了。下面举几个例子。

String 转对 应编码的 byte[]

这里假设要转成 utf-8。

1
2
String str = “字符串”; // 这里不在乎系统的默认编码
byte[] utf8bytes = str.getBytes("UTF-8");

已知编码的 byte[] 转对应编码 String

1
2
3
byte[] gbkBytes = {...}; // 已知字节数组为 gbk
String gbkStr = new String(gbkBytes, "GBK"); // 首先要转成GBK字符串
String utf8Str = new String(gbkStr.getBytes("UTF-8"), "UTF-8");

其他格式互转同理。

0%