代码如下:
String str = "中文";
byte[] utf8b = str.getBytes("UTF-8");
byte[] gbkb = str.getBytes("GBK");
// 没有乱码
System.out.println(new String(utf8b, "UTF-8"));
// 没有乱码
System.out.println(new String(gbkb, "GBK"));
// 有乱码
System.out.println(new String(gbkb, "UTF-8"));
// 有乱码
System.out.println(new String(utf8b, "GBK"));
java中的String永远都是Unicode编码的,以它作为中间结果转化成各种不同的编码格式。
String str = "中文";
"中文"这个字符串的编码是根据操作系统的默认编码而定的,如果我们在中文的windows下开发,那这个"中文"字符串的编码是GBK。将"中文"字符串赋给str变量的时候,jvm会将"中文"有GBK转为Unicode编码,再把这个"中文"字符串赋给str变量。
byte[] utf8b = str.getBytes("UTF-8");
java String.getBytes(String charset)这个方法返回一个字串的字节数组,这里的字节是charset格式的。如果没有charset这个参数,则返回该操作系统默认的编码格式的字节数组。
这里的str是Unicode编码的,在这行代码中,jvm实际上是做了这样的转化 UNICODE => UTF-8,就是将Jvm内存中的unicode编码二进制码转化成UTF-8格式的二进制码然后赋值给byte[] utf8b 。这个转化的过程我们不用管,jvm会根据一个编码格式对照表来转化。
byte[] gbkb = str.getBytes("GBK");
同上。
System.out.println(new String(utf8b, "UTF-8"));
这里的二个参数"UTF-8"告诉jvm:“当前utf8b的编码格式是"UTF-8",你就以这个格式转化成unicode吧!”。也就是将utf8b转化成unicode再存入Jvm的内存,utf8=>unicode。(这个参数应该是为了告诉jvm使用“UTF-8”的编码格式对照表来转化)
System.out.println(new String(gbkb, "GBK"));
同上。
System.out.println(new String(gbkb, "UTF-8"));
这里gbkb保存的是gbk编码的字节,而这里的"UTF-8"告诉jvm 字节数组gbkb的编码格式是"UTF-8",jvm就会试图将原来是"GBK"格式的数据使用"UTF-8"的对照表来转化成unicode,结果当然是牛头不对马嘴了。
修改于:http://cai555.iteye.com/blog/661191