乱码问题根源:编码与解码所用的字符编码方式不一致
编码: 从文字到0、1的映射
解码: 从0、1到文字的映射
乱码问题展示代码:
//使用指定的编码方式将此String编码为字节数组
byte[] b_GBK = "你".getBytes("GBK");
byte[] b_UTF8 = "你".getBytes("UTF-8");
byte[] b_ISO88591 = "你".getBytes("ISO8859-1");
//不同的编码方式编码同样的字符所对应的映射规则是不一样的
System.out.println(Arrays.toString(b_GBK));
System.out.println(Arrays.toString(b_UTF8));
System.out.println(Arrays.toString(b_ISO88591));
//对字节数组按照指定的字符编码方式解码
System.out.println(new String(b_UTF8, "UTF-8"));
System.out.println(new String(b_UTF8, "ISO8859-1"));
System.out.println(new String(b_ISO88591, "UTF-8"));
输出为:
[-60, -29]
[-28, -67, -96]
[63]
你
ä½
?
第二行乱码因为:编码UTF-8,解码ISO8859-1,编解码所用的字符编码方式不一致
第三行乱码因为:编码ISO8859-1,解码UTF-8,同上
结论:只要保持编解码所用的字符编码方式一致就可以避免乱码
但有时会遇到我们获取到的数据已经按错误的字符编码方式解码的情况,那么如何复原呢?
解决思路:
- 1.按错误字符编码方式编码(复原为原始byte数组)
- 2.按正确字符编码方式解码
示例代码:
//UTF-8编码
byte[] b_utf = "你".getBytes("UTF-8");
//ISO8859-1解码
String before = new String(b_utf, "ISO8859-1");
System.out.println("before = " + before);
//已经乱码,乱码后续处理:
//ISO8859-1编码(复原字节数据)
byte[] b_iso = before.getBytes("ISO8859-1");
//UTF-8解码(正确解码)
String after = new String(b_iso, "UTF-8");
System.out.println("after = " + after);
输出为:
before = ä½
after = 你