lotusswan

            BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
            11 Posts :: 0 Stories :: 4 Comments :: 0 Trackbacks
          在你查閱Java 5.0 JDK文檔時(shí),當(dāng)你發(fā)現(xiàn)Character類(lèi)的每個(gè)方法幾乎都有相應(yīng)的重載體時(shí),千萬(wàn)不要覺(jué)得奇怪。如果你細(xì)心的話(huà),你肯定會(huì)發(fā)現(xiàn),重載的方法差別幾乎都在參數(shù)類(lèi)型上,某個(gè)方法的參數(shù)類(lèi)型是char,而對(duì)應(yīng)的重載方法的參數(shù)則為int。拿我們最重用的一個(gè)方法isUpperCase 來(lái)說(shuō),就有兩種定義:public static boolean isUpperCase(char ch)和public static boolean isUpperCase(int codePoint),前者是我們常用的,相信大家都不會(huì)感到奇怪。那么,后者用來(lái)干什么呢?既然都有了前一個(gè)方法,為什么還要有后面的這個(gè)重載方法呢?之所以這樣,是因?yàn)镴ava 5.0需要更好地支持Unicode編碼。

          我們知道,任何事物都是在進(jìn)化和發(fā)展中的,Unicode編碼也不例會(huì)。Java 5.0以前的JDK支持的是Unicode 3.0,而Java 5.0支持的則是Unicode 4.0。在Unicode 4.0中,定義了一些僅用16位無(wú)法表示的字符。既然無(wú)法用16位表示,而Java 5.0又支持這些字符,那么必然需要表示這些字符,顯然用char類(lèi)型來(lái)表示肯定是不可能了,所以Java 5.0中用int類(lèi)型來(lái)表示這些字符。既然表示字符的數(shù)據(jù)類(lèi)型發(fā)生了變化,對(duì)應(yīng)的方法自然也應(yīng)該與時(shí)俱進(jìn)了。

          說(shuō)完了原因,我們來(lái)了解幾個(gè)概念。首先說(shuō)說(shuō)代碼點(diǎn)(codepoint),它是一個(gè)數(shù)值,用來(lái)表示一個(gè)特定的字符,例如符號(hào)“派"(3.1415926)的代碼點(diǎn)就是0x3c0。另外一個(gè)概念是BMP(Basic Multilingual Plan ),指的是一個(gè)Java char類(lèi)型(16位)所能表示的所有字符對(duì)應(yīng)的代碼點(diǎn)集合,其范圍可想而知,從\u0000到\uffff;最后一個(gè)概念是增補(bǔ)字符,估計(jì)這個(gè)概念大家都知道表示什么了。對(duì)了,它用來(lái)表示那些16位無(wú)法表示的字符所對(duì)應(yīng)的代碼點(diǎn)。增補(bǔ)字符的代碼點(diǎn)對(duì)應(yīng)的數(shù)據(jù)類(lèi)型雖然是int類(lèi)型,但其范圍卻不是整個(gè)int類(lèi)型的取值范圍,而只是其子集:0x10000到0x10ffff。可見(jiàn)增補(bǔ)字符只用到了int類(lèi)型的后21位,而前11位則統(tǒng)一置為0,暫時(shí)不使用。

          對(duì)于單個(gè)字符而言,其處理還是比較簡(jiǎn)單的,如果我們需要用到unicode 4.0定義的那些額外字符,我們使用int類(lèi)型來(lái)表示;如果我們不需要,我們直接使用char類(lèi)型來(lái)表示就可以了。但現(xiàn)實(shí)往往是殘酷的,很多時(shí)候,我們可能希望將這些字符組合起來(lái)使用,更糟的是,可能這些組合中既包含16位能表示的,也不含16位表示不了的,我們?cè)撛趺崔k呢?為了解決此問(wèn)題,Java引入了兩類(lèi)API,這兩類(lèi)API都是基于代碼點(diǎn)的:用于各種?char 和基于代碼點(diǎn)的表示法之間轉(zhuǎn)換的方法和用于分析和映射代碼點(diǎn)的方法。這兩類(lèi)方法都在Character類(lèi)中定義,char和代碼點(diǎn)轉(zhuǎn)換的方法分別為toChars(int codePoint)和toEndPoint(char high, char low);檢測(cè)代碼點(diǎn)的方法則為Character 類(lèi)中的isHighSurrogate 和isLowSurrogate 方法和charCount(int codePoint)方法。前兩個(gè)方法可以識(shí)別用于表示增補(bǔ)字符的char值;而最后一個(gè)方法可以確定是否需要將某個(gè)代碼點(diǎn)轉(zhuǎn)換為一個(gè)或兩個(gè)char。

          為了體會(huì)這幾個(gè)方法的使用,我們可以看一下下面的示例:
          package ?com.jiang.tiger.chap1;

          public ? class ?CharacterTester?
          {
          ????
          private ? static ? final ? int []?code? = ? { 0x105600 , 0x105601 ,? 0x105700 ,? 0x10f255 ,? 0x02f945 ,? 0x036548 }
          ;
          ????
          ????
          public ? static ?String?toStr()?
          {
          ????????String?str?
          = ? new ?String(code,? 0
          ,?code.length);
          ????????
          return
          ?str;
          ????}

          ????
          ????
          public ? static ? void ?printChar()? {
          ????????
          int ?length? =
          ?code.length;
          ????????
          char []?ch? = ? new ? char [ 2
          ];
          ????????
          for ( int ?i? = ? 0 ;?i? < length;?i ++ ?)?
          {
          ????????????ch?
          =
          ?Character.toChars(code[i]);
          ????????????System.out.printf(
          " code[%d]?=?0x%x "
          ,?i,?code[i]);
          ????????????System.out.println();
          ????????????System.out.printf(
          " ch[0]?=?0x%x,?ch[1]?=?0x%x,?sum?=?0x%x " ,( int )ch[ 0 ],?( int )ch[ 1 ],?( int )(ch[ 0 ]? + ?ch[ 1
          ]));
          ????????????System.out.println();
          ????????????System.out.printf(
          " back[%d]?=?0x%x " ,?i,?Character.toCodePoint(ch[ 0 ],?ch[ 1
          ]));
          ????????????System.out.println();????????
          ????????}

          ????????System.out.println(
          " ch[0]?is?highSurrogate:? " ? + ?Character.isHighSurrogate(ch[ 0 ]));
          ????????System.out.println(
          " ch[1]?is?LowSurrogate:? " ? + ?Character.isLowSurrogate(ch[ 1
          ]));
          ????????System.out.println(
          " ch[1]?is??HighSurrogate:? " ? + ?Character.isHighSurrogate(ch[ 1
          ]));
          ????????System.out.println(
          " 0xcdff?is?LowSurrogate:? " ? + ?Character.isHighSurrogate(( char ) 0xcdff
          ));
          ????}

          ????
          ????
          public ? static ? char []?toChar()? {
          ????????
          int ?length? =
          ?code.length;
          ????????
          char []?result? = ? new ? char [ 2 ? *
          ?length];
          ????????
          char []?ch? = ? new ? char [ 2
          ];
          ????????
          for ?( int ?i? = ? 0 ;?i? < ?length;?i ++ )?
          {
          ????????????ch?
          =
          ?Character.toChars(code[i]);
          ????????????result[
          2 ? * ?i]? = ?ch[ 0
          ];
          ????????????result[
          2 ? * ?i? + ? 1 ]? = ?ch[ 1
          ];
          ????????}

          ????????
          return ?result;
          ????}

          ????
          ????
          public ? static ? void ?main(String[]?args)? {
          ????????String?str?
          =
          ?CharacterTester.toStr();
          ????????System.out.println(
          " length?=? " ? +
          ?str.length());
          ????????
          ????????String?str2?
          = ?str? + ? " char "
          ;
          ????????System.out.println(
          " length?=? " ? +
          ?str2.length());
          ????????
          ????????CharacterTester.printChar();
          ????????
          ????????
          char []?ch? =
          ?CharacterTester.toChar();
          ????????System.out.printf(
          " code[1]?=?0x%x " ,?Character.codePointAt(ch,? 2
          ));
          ????????System.out.println();
          ????????
          ????}

          ????

          }

          上面示例的運(yùn)行結(jié)果如下所示:
          length? = ? 12
          length?
          = ? 16
          code
          [ 0 ] ? = ?0x105600
          ch
          [ 0 ] ? = ?0xdbd5 , ?ch [ 1 ] ? = ?0xde00 , ?sum? = ?0x1b9d5
          back
          [ 0 ] ? = ?0x105600
          code
          [ 1 ] ? = ?0x105601
          ch
          [ 0 ] ? = ?0xdbd5 , ?ch [ 1 ] ? = ?0xde01 , ?sum? = ?0x1b9d6
          back
          [ 1 ] ? = ?0x105601
          code
          [ 2 ] ? = ?0x105700
          ch
          [ 0 ] ? = ?0xdbd5 , ?ch [ 1 ] ? = ?0xdf00 , ?sum? = ?0x1bad5
          back
          [ 2 ] ? = ?0x105700
          code
          [ 3 ] ? = ?0x10f255
          ch
          [ 0 ] ? = ?0xdbfc , ?ch [ 1 ] ? = ?0xde55 , ?sum? = ?0x1ba51
          back
          [ 3 ] ? = ?0x10f255
          code
          [ 4 ] ? = ?0x2f945
          ch
          [ 0 ] ? = ?0xd87e , ?ch [ 1 ] ? = ?0xdd45 , ?sum? = ?0x1b5c3
          back
          [ 4 ] ? = ?0x2f945
          code
          [ 5 ] ? = ?0x36548
          ch
          [ 0 ] ? = ?0xd899 , ?ch [ 1 ] ? = ?0xdd48 , ?sum? = ?0x1b5e1
          back
          [ 5 ] ? = ?0x36548
          ch
          [ 0 ] ?is?highSurrogate:?true
          ch
          [ 1 ] ?is?LowSurrogate:?true
          ch
          [ 1 ] ?is??HighSurrogate:?false
          0xcdff?is?LowSurrogate:?false
          code
          [ 1 ] ? = ?0x105601

          Java對(duì)Unicode4.0的支持是新引入的一個(gè)功能,涉及的面很廣,作出修改的類(lèi)也比較多,因此關(guān)于java對(duì)Unicode的支持的內(nèi)容很多,本文只是拋磚引玉。如果對(duì)此感興趣的讀者,可以參考JDK,或是《Java 平臺(tái)中的增補(bǔ)字符》一文,該文鏈接為 http://gceclub.sun.com.cn/developer/technicalArticles/Intl/Supplementary/index_zh_CN.html
          posted on 2006-11-27 23:51 lotusswan 閱讀(2276) 評(píng)論(1)  編輯  收藏 所屬分類(lèi): Tiger學(xué)習(xí)筆記

          Feedback

          # re: Java 5.0對(duì)Unicode碼的支持 2011-09-02 12:28 censhao
          好文章   回復(fù)  更多評(píng)論
            

          主站蜘蛛池模板: 五河县| 汪清县| 余干县| 内乡县| 交城县| 个旧市| 康保县| 都安| 临城县| 奈曼旗| 新和县| 津市市| 肥城市| 六安市| 临城县| 衡南县| 平泉县| 防城港市| 东山县| 齐齐哈尔市| 利川市| 博客| 贺州市| 全南县| 北流市| 高邮市| 菏泽市| 晴隆县| 梓潼县| 镇远县| 灵川县| 渝中区| 佛坪县| 黑山县| 察哈| 都匀市| 梁平县| 根河市| 商洛市| 县级市| 句容市|