天天看点

Java核心技术卷I基础知识3.3.4 Unicode和char类型

<b>3.3.4 unicode和char类型</b>

要想弄清char类型,就必须了解unicode编码机制。unicode打破了传统字符编码机制的限制。在unicode出现之前,已经有许多种不同的标准:美国的ascii、西欧语言中的iso 8859-1、俄罗斯的koi-8、中国的gb 18030和big-5等。这样就产生了下面两个问题:一个是对于任意给定的代码值,在不同的编码方案下有可能对应不同的字母;二是采用大字符集的语言其编码长度有可能不同。例如,有些常用的字符采用单字节编码,而另一些字符则需要两个或更多个字节。

设计unicode编码的目的就是要解决这些问题。在20世纪80年代开始启动设计工作时,人们认为两个字节的代码宽度足以对世界上各种语言的所有字符进行编码,并有足够的空间留给未来的扩展。在1991年发布了unicode 1.0,当时仅占用65 536个代码值中不到一半的部分。在设计java时决定采用16位的unicode字符集,这样会比使用8位字符集的程序设计语言有很大的改进。

十分遗憾,经过一段时间,不可避免的事情发生了。unicode字符超过了65 536个,其主要原因是增加了大量的汉语、日语和韩语中的表意文字。现在,16位的char类型已经不能满足描述所有unicode字符的需要了。

下面利用一些专用术语解释一下java语言解决这个问题的基本方法。从java

se 5.0开始。码点(code point)是指与一个编码表中的某个字符对应的代码值。在unicode标准中,码点采用十六进制书写,并加上前缀u+,例如u+0041就是拉丁字母a的码点。unicode的码点可以分成17个代码级别(code plane)。第一个代码级别称为基本的多语言级别(basic multilingual plane),码点从u+0000到u+ffff,其中包括经典的unicode代码;其余的16个级别码点从u+10000到u+10ffff,其中包括一些辅助字符(supplementary character)。

utf-16编码采用不同长度的编码表示所有unicode码点。在基本的多语言级别中,每个字符用16位表示,通常被称为代码单元(code unit);而辅助字符采用一对连续的代码单元进行编码。这样构成的编码值落入基本的多语言级别中空闲的2048字节内,通常被称为替代区域(surrogate area)[u+d800~u+dbff用于第一个代码单元,u+dc00~u+dfff用于第二个代码单元]。这样设计十分巧妙,我们可以从中迅速地知道一个代码单元是一个字符的编码,还是一个辅助字符的第一或第二部分。例如,是八元数集(http://math.ucr.edu/home/baez/octonions)的一个数学符号,码点为u+1d546,编码为两个代码单元u+d835和u+dd46。(关于编码算法的具体描述见http://en.wikipedia.org/wiki/utf-16)。

在java中,char类型描述了utf-16编码中的一个代码单元。

我们强烈建议不要在程序中使用char类型,除非确实需要处理utf-16代码单元。最好将字符串作为抽象数据类型处理(有关这方面的内容将在3.6节讨论)。