很多文章搞长篇大论大讲特讲人类为了让计算机能够准确表示各种字符的演化历史,这完全是没有必要的,几句话就能说明白。
"字符集"和"字符集编码"是两回事
字符集(Charset Set),仅仅是一套从【字符】到【数字】的映射字典,它只规定了应该用什么数字来标识字符,仅此而已,至于计算机在存储的时候应该用什么字节来标识,字符集是根本不管这事的。Unicode, GB2312, ASCII都属于字符集。
字符集编码(Character Encoding),专门规定了字符集中的字符在计算机中应该如何存储,说白了就是怎么用字节来表示他们。UTF8, UTF16, 都属于字符集编码。
大家感受到区别了么,如果把字符集比作立了一套法律,那么字符集编码就是法律的执行方式。只立法而不去执行则立法毫无意义,字符集也是如此。只有字符集而没有规定如何编码,那对于计算机来说也毫无用处。因为在计算机看来,世间万物都是字节,而只有将人类规定的字符集【编码】成字节,计算机才能识别和存储。
有人既是字符集,又是字符集编码
注意这里有一个地方非常容易混淆,那就是有的人【既是字符集,又是字符集编码】。比如GB2312作为字符集的时候,规定了“你”这个汉字用十六进制的0xC4E3
来表示,同时GB2312又是编码规范,因此在计算机中,可以直接使用0xC4E3
来存储“你”。ASNII也是同理,都属于字符集跟其编码完全一致的玩意。
而Unicode就不一样了,想要存储Unicode中规定的字符,就必须使用另一种编码方式对其进行编码,比如UTF8就是一种使用1~3个字节来表示的一种编码方式。
Java
在Java语言里,它使用的是Unicode字符集,和UTF16的编码。也就是说Java能表示出全部Unicode字符集中规定了的字符,然后在内存中存储时,通过UTF16中定义的规则,将其转换成字节。例如“a”这个字母,在Unicode中规定要用十六进制下的0x61
来表示,但是实际存储的时候可不是直接存的0x61
,而是查UTF16表,发现应该是0x0061
。所以,Java中一个char类型在内存中占用两个字节,因为他们存储的是UTF16编码后的字符,而UTF16则是把所有Unicode字符都使用固定了两字节的方式进行编码。
网友评论