字符集与字符编码是两个不同的概念。
字符集,顾名思义就是字符的集合,比如ASCII字符集包含了a-z A-Z 0-9 半角标点符号和特殊控制符号在内的128个符号。对于一个字符集来说,要正确编码转码一个字符需要三个元素:字库表、编码字符集、字符编码。字库表是所有字符的数据库,字库表决定了整个字符集能够展现表示的所有字符的范围。编码字符集,即用一个编码来表示字符在字库表中的位置,比如ASCII字符集中,A排在65位。字符编码,即编码字符集和实际存储值之间的转换关系,一般来说直接将编码字符集作为实际存储值。例如ASCII中,A排在65位,而编码后A的数值是0100 0001也即十进制的65的二进制转换结果。
常见的字符集:
Unicode:也叫统一字符集,它包含了几乎世界上所有的已经发现且需要使用的字符(如中文、日文、英文、德文等)。
ASCII:早期的计算机系统只能处理英文,所以ASCII也就成为了计算机的缺省字符集,包含了英文所需要的所有字符。
GB2312:中文字符集,包含ASCII字符集。ASCII部分用单字节表示,剩余部分用双字节表示。
GBK:GB2312的扩展,但完整包含了GB2312的所有内容。
GB18030:GBK字符集的超集,常叫大汉字字符集,也叫CJK(Chinese,Japanese,Korea)字符集,包含了中、日、韩三国语言中的所有字符。
常见的字符编码:
字符编码 | 每个字符字节数 |
ASCII | 1 |
UCS-2(Unicode) | 2 |
UCS-4(Unicode) | 4 |
UTF-8(Unicode) | 1 - 6 |
UTF-16(Unicode) | 2 - 4 |
GBK/GB2312(中文) | 1 - 2 |
GB18030(CJK) | 1 - 4 |
从以上介绍,我们不难区分unicode和utf-8,utf-16的关系:
unicode是字符集,unicode分为USC-2和USC-4两种编码方式,也就是使用2个字节和4个自己来存储字符。目前存在的有UTF7,UTF8,UTF16和UTF32这几种。其中UTF-16规则对应USC-2编码,而UTF-32规则对应USC-4编码。而UTF-7和UTF8比较特殊。我们平常说的unicode编码其实就是utf-16,固定两个字节来编码字符。
在java的内存中,String是以unicode(utf-16)的编码方式存储字符串。我们分析String的源码可以看到,String包含一个char[]数组,比如:“中文”,String内部就是用char[‘中’, ‘文’]数组存储,而char在java中是占两个字节,在内存中的存储方式正是unicode(utf-16)方式。