天天看點

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節讨論)。