基础知识
字符串内部表示
Unicode 是一种编码,所谓的编码就是一个编号(数字)到字符的一种映射关系,就仅仅是一种一对一的映射关系而已。 GBK、UTF-8是一种编码格式,是用来序列化或存储上述的(编号或者数字)的一种“格式”。 编码和编码格式:java的String使用的编码的Unicode,当String存在于内存中的时候,是“只有编码没有编码格式的”,所以java程序中的任何String对象,说它是GBK或者UTF-8都是错的。String在内存中是不存在编码格式*的,它只是一个Unicode的一个字符而已。 如果源码文件是某种编码, 操作系统默认的环境编码为这种编码,那么编译时, JVM将按照这种编码将字节数组解析成字符,然后将字符转换为unicode格式的字节数组,作为内部存储。
乱码的原因
由于字符串原本的编码格式与读取时解析用的编码格式不一致。
判断如何造成乱码的方法
String s = "你好哦!";
System.out.println( new String(s.getBytes(), StandardCharsets.UTF_8));
System.out.println( new String(s.getBytes(), "GBK"));
System.out.println( new String(s.getBytes(), StandardCharsets.ISO_8859_1));
System.out.println( new String(s.getBytes("GBK"), StandardCharsets.UTF_8));
System.out.println( new String(s.getBytes("GBK"), "GBK"));
System.out.println( new String(s.getBytes("GBK"), StandardCharsets.ISO_8859_1));
//操作系统默认编码为UTF-8,输出为
你好哦!
浣犲ソ鍝�!
ä½ å¥½å¦!
���Ŷ!
你好哦!
ÄãºÃŶ!
解决乱码的方法
//判断出是如何造成现在的乱码后
//如:是因为 new String(s.getBytes("GBK"), StandardCharsets.UTF_8) (���Ŷ!)
//则反向编码,可以使最后还原
String s = "你好哦!我很好";
String gbk = new String(s.getBytes(StandardCharsets.UTF_8), "GBK");
System.out.println(gbk);//浣犲ソ鍝︼紒鎴戝緢濂�
String utf = new String(gbk.getBytes("GBK"), StandardCharsets.UTF_8);
System.out.println(utf);//你好哦!我很�?
还是可能会错
s.getBytes()
将unicode 转换为操作系统默认的格式的字节数组 可指定编码:s.getBytes("GBK")
new String (bytes, Charset)
charset是指定读取bytes的方式,这里指定为UTF-8,即把bytes的内容当做UTF-8格式对待。
常见编码
ASCII:美国标准信息交换表
ISO8859-1:拉丁码表,欧洲码表
GB2312:中国的中文编码表
GBK:中国的中文编码表升级
GB18030:GBK的取代版本
BIG5:通用于香港、台湾地区的繁体字编码方案
UTF-8:最多用3个子节表示一个字符
Unicode:国际标准码,融合了多种文字,所有的文字都用两个子节来表示,Java语言使用的就是该码表