字符集与字符编码是两个不同的概念。

字符集,顾名思义就是字符的集合,比如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)方式。