天天看點

Java(TM) 平台中的增補字元

<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script> <script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>

  摘要

  本文介紹 Java 平台支援增補字元的方式。增補字元是 Unicode 标準中代碼點超出 U+FFFF 的字元,是以它們無法在 Java 程式設計語言中描述為單個的 16 位實體(例如 char 資料類型)。這些字元一般極少用,但是,有些會在諸如中文或日文人名中用到,是以,在東亞國家,政府應用程式通常會要求支援這些字元。

  Java 平台目前正在改進,以便支援對增補字元的處理,這種改進對現有的應用程式影響微乎其微。新的低層 API 在需要時能夠使用單個的字元運作。不過,大多數文本處理 API 均使用字元序列,例如 String 類或字元數組。現在,這些均解釋為 UTF-16 序列,而且,這些 API 實作已轉變為正确地處理增補字元。這些改進已融入 Java 2 平台 1.5 版,标準版 (J2SE)。

  除詳細解釋這些改進之外,本文同時為應用程式開發人員确定和實作必要的更改提供指導,以支援整個 Unicode 字元集的使用。

  背景

  Unicode 最初設計是作為一種固定寬度的 16 位字元編碼。在 Java 程式設計語言中,基本資料類型 char 初衷是通過提供一種簡單的、能夠包含任何字元的資料類型來充分利用這種設計的優點。不過,現在看來,16 位編碼的所有 65,536 個字元并不能完全表示全世界所有正在使用或曾經使用的字元。于是,Unicode 标準已擴充到包含多達 1,112,064 個字元。那些超出原來的 16 位限制的字元被稱作增補字元。Unicode 标準 2.0 版是第一個包含啟用增補字元設計的版本,但是,直到 3.1 版才收入第一批增補字元集。由于 J2SE 的 1.5 版必須支援 Unicode 标準 4.0 版,是以它必須支援增補字元。

  對增補字元的支援也可能會成為東亞市場的一個普遍商業要求。政府應用程式會需要這些增補字元,以正确表示一些包含罕見中文字元的姓名。出版應用程式可能會需要這些增補字元,以表示所有的古代字元和變體字元。中國政府要求支援 GB18030(一種對整個 Unicode 字元集進行編碼的字元編碼标準),是以,如果是 Unicode 3.1 版或更新版本,則将包括增補字元。台灣标準 CNS-11643 包含的許多字元在 Unicode 3.1 中列為增補字元。香港政府定義了一種針對粵語的字元集,其中的一些字元是 Unicode 中的增補字元。最後,日本的一些供應商正計劃利用增補字元空間中大量的專用空間收入 50,000 多個日文漢字字元變體,以便從其專有系統遷移至基于 Java 平台的解決方案。

  是以,Java 平台不僅需要支援增補字元,而且必須使應用程式能夠友善地做到這一點。由于增補字元打破了 Java 程式設計語言的基礎設計構想,而且可能要求對程式設計模型進行根本性的修改,是以,Java Community Process 召集了一個專家組,以期找到一個适當的解決方案。該小組被稱為 JSR-204 專家組,使用 Unicode 增補字元支援的 Java 技術規範請求的編号。從技術上來說,該專家組的決定僅适用于 J2SE 平台,但是由于 Java 2 平台企業版 (J2EE) 處于 J2SE 平台的最上層,是以它可以直接受益,我們期望 Java 2 平台袖珍版 (J2ME) 的配置也采用相同的設計方法。

  不過,在了解 JSR-204 專家組确定的解決方案之前,我們需要先了解一些術語。

  代碼點、字元編碼方案、UTF-16:這些是指什麼?

  不幸的是,引入增補字元使字元模型變得更加複雜了。在過去,我們可以簡單地說“字元”,在一個基于 Unicode 的環境(例如 Java 平台)中,假定字元有 16 位,而現在我們需要更多的術語。我們會盡量介紹得相對簡單一些 — 如需了解所有詳細的讨論資訊,您可以閱讀 Unicode 标準第 2 章或 Unicode 技術報告 17“TMl" />字元編碼模型”。Unicode 專業人士可略過所有介紹直接參閱本部分中的最後定義。

  字元是抽象的最小文本機關。它沒有固定的形狀(可能是一個字形),而且沒有值。“A”是一個字元,“€”(德國、法國和許多其他歐洲國家通用貨币的标志)也是一個字元。

  字元集是字元的集合。例如,漢字字元是中國人最先發明的字元,在中文、日文、韓文和越南文的書寫中使用。

  編碼字元集是一個字元集,它為每一個字元配置設定一個唯一數字。Unicode 标準的核心是一個編碼字元集,字母“A”的編碼為 004116 和字元“€”的編碼為 20AC16。Unicode 标準始終使用十六進制數字,而且在書寫時在前面加上字首“U+”,是以“A”的編碼書寫為“U+0041”。

  代碼點是指可用于編碼字元集的數字。編碼字元集定義一個有效的代碼點範圍,但是并不一定将字元配置設定給所有這些代碼點。有效的 Unicode 代碼點範圍是 U+0000 至 U+10FFFF。Unicode 4.0 将字元配置設定給一百多萬個代碼點中的 96,382 代碼點。

  增補字元是代碼點在 U+10000 至 U+10FFFF 範圍之間的字元,也就是那些使用原始的 Unicode 的 16 位設計無法表示的字元。從 U+0000 至 U+FFFF 之間的字元集有時候被稱為基本多語言面 (BMP)。是以,每一個 Unicode 字元要麼屬于 BMP,要麼屬于增補字元。

  字元編碼方案是從一個或多個編碼字元集到一個或多個固定寬度代碼單元序列的映射。最常用的代碼單元是位元組,但是 16 位或 32 位整數也可用于内部處理。UTF-32、UTF-16 和 UTF-8 是 Unicode 标準的編碼字元集的字元編碼方案。

  UTF-32 即将每一個 Unicode 代碼點表示為相同值的 32 位整數。很明顯,它是内部處理最友善的表達方式,但是,如果作為一般字元串表達方式,則要消耗更多的記憶體。

  UTF-16 使用一個或兩個未配置設定的 16 位代碼單元的序列對 Unicode 代碼點進行編碼。值 U+0000 至 U+FFFF 編碼為一個相同值的 16 位單元。增補字元編碼為兩個代碼單元,第一個單元來自于高代理範圍(U+D800 至 U+DBFF),第二個單元來自于低代理範圍(U+DC00 至 U+DFFF)。這在概念上可能看起來類似于多位元組編碼,但是其中有一個重要差別:值 U+D800 至 U+DFFF 保留用于 UTF-16;沒有這些值配置設定字元作為代碼點。這意味着,對于一個字元串中的每個單獨的代碼單元,軟體可以識别是否該代碼單元表示某個單單元字元,或者是否該代碼單元是某個雙單元字元的第一個或第二單元。這相當于某些傳統的多位元組字元編碼來說是一個顯著的改進,在傳統的多位元組字元編碼中,位元組值 0x41 既可能表示字母“A”,也可能是一個雙位元組字元的第二個位元組。

  UTF-8 使用一至四個位元組的序列對編碼 Unicode 代碼點進行編碼。U+0000 至 U+007F 使用一個位元組編碼,U+0080 至 U+07FF 使用兩個位元組,U+0800 至 U+FFFF 使用三個位元組,而 U+10000 至 U+10FFFF 使用四個位元組。UTF-8 設計原理為:位元組值 0x00 至 0x7F 始終表示代碼點 U+0000 至 U+007F(Basic Latin 字元子集,它對應 ASCII 字元集)。這些位元組值永遠不會表示其他代碼點,這一特性使 UTF-8 可以很友善地在軟體中将特殊的含義賦予某些 ASCII 字元。

  下表所示為幾個字元不同表達方式的比較:

  unicode 代碼點

  表示字形

  utf-32 代碼單元

  00000041

  000000DF

  00006771

  00010400

  utf-16 代碼單元

  0041

  00DF

  6771

  D801

  DC00

  utf-8 代碼單元

  41

  C3

  9F

  E6

  9D

  B1

  F0

  90

  90

  80

  另外,本文在許多地方使用術語字元序列或 char 序列概括 Java 2 平台識别的所有字元序列的容器:char[], Java.lang.CharSequence 的實作(例如 String 類),和 Java.text.CharacterIterator 的實作。

  這麼多術語。它們與在 Java 平台中支援增補字元有什麼關系呢?

  Java 平台中增補字元的設計方法

  JSR-204 專家組必須作出的主要決定是如何在 Java API 中表示增補字元,包括單個字元和所有形式的字元序列。專家組考慮并排除了多種方法:

  重新定義基本類型 char,使其具有 32 位,這樣也會使所有形式的 char 序列成為 UTF-32 序列。

  在現有的 16 位類型 char 的基礎上,為字元引入一種新的 32 位基本類型(例如,char32)。所有形式的 Char 序列均基于 UTF-16。

  在現有的 16 位類型 char 的基礎上,為字元引入一種新的 32 位基本類型(例如,char32)。String 和 StringBuffer 接受并行 API,并将它們解釋為 UTF-16 序列或 UTF-32 序列;其他 char 序列繼續基于 UTF-16。

  使用 int 表示增補的代碼點。String 和 StringBuffer 接受并行 API,并将它們解釋為 UTF-16 序列或 UTF-32 序列;其他 char 序列繼續基于 UTF-16。

  使用代理 char 對,表示增補代碼點。所有形式的 char 序列基于 UTF-16。

  引入一種封裝字元的類。String 和 StringBuffer 接受新的 API,并将它們解釋為此類字元的序列。

  使用一個 CharSequence 執行個體和一個索引的組合表示代碼點。

  在這些方法中,一些在早期就被排除了。例如,重新定義基本類型 char,使其具有 32 位,這對于全新的平台可能會非常有吸引力,但是,對于 J2SE 來說,它會與現有的 Java 虛拟機TMl/2004-05-26/character.hTMl#tjvm" />1、序列化和其他接口不相容,更不用說基于 UTF-32 的字元串要使用兩倍于基于 UTF-16 的字元串的記憶體了。添加一種新類型的 char32 可能會簡單一些,但是仍然會出現虛拟機和序列化方面的問題。而且,語言更改通常需要比 API 更改有更長的提前期,是以,前面兩種方法會對增補字元支援帶來無法接受的延遲。為了在餘下的方法中篩選出最優方案,實作小組使用四種不同的方法,在大量進行低層字元處理的代碼(Java.util.regex 包)中實作了對增補字元支援,并對這四種方法的難易程度和運作表現進行了比較。

  最終,專家組确定了一種分層的方法:

  使用基本類型 int 在低層 API 中表示代碼點,例如 Character 類的靜态方法。

  将所有形式的 char 序列均解釋為 UTF-16 序列,并促進其在更高層級 API 中的使用。

  提供 API,以友善在各種 char 和基于代碼點的表示法之間的轉換。

  在需要時,此方法既能夠提供一種概念簡明且高效的單個字元表示法,又能夠充分利用通過改進可支援增補字元的現有 API。同時,還能夠促進字元序列在單個字元上的應用,這一點一般對于國際化的軟體很有好處。

  在這種方法中,一個 char 表示一個 UTF-16 代碼單元,這樣對于表示代碼點有時并不夠用。您會注意到,J2SE 技術規範現在使用術語代碼點和 UTF-16 代碼單元(表示法是相關的)以及通用術語字元(表示法與該讨論沒有關系)。API 通常使用名稱 codePoint 描述表示代碼點的類型 int 的變量,而 UTF-16 代碼單元的類型當然為 char。

  我們将在下面兩部分中了解到 J2SE 平台的實質變化 — 其中一部分介紹單個代碼點的低層 API,另一部分介紹采用字元序列的高層接口。

  開放的增補字元:基于代碼點的 API

  新增的低層 API 分為兩大類:用于各種 char 和基于代碼點的表示法之間轉換的方法和用于分析和映射代碼點的方法。

  最基本的轉換方法是 Character.toCodePoint(charhigh, charlow)(用于将兩個 UTF-16 代碼單元轉換為一個代碼點)和 Character.toChars(intcodePoint)(用于将指定的代碼點轉換為一個或兩個 UTF-16 代碼單元,然後封裝到一個 char[] 内。不過,由于大多數情況下文本以字元序列的形式出現,是以,另外提供 codePointAt 和 codePointBefore 方法,用于将代碼點從各種字元序清單示法中提取出來:Character.codePointAt(char[]a, intindex) 和 String.codePointBefore(int index) 是兩種典型的例子。在将代碼點插入字元序列時,大多數情況下均有一些針對 StringBuffer 和 StringBuilder 類的 appendCodePoint(int codePoint) 方法,以及一個用于提取表示代碼點的 int[] 的 String 建構器。

  幾種用于分析代碼單元和代碼點的方法有助于轉換過程:Character 類中的 isHighSurrogate 和 isLowSurrogate 方法可以識别用于表示增補字元的 char 值;charCount(int codePoint) 方法可以确定是否需要将某個代碼點轉換為一個或兩個 char。

  但是,大多數基于代碼點的方法均能夠對所有 Unicode 字元實作基于 char 的舊方法對 BMP 字元所實作的功能。以下是一些典型例子:

  Character.isLetter(int codePoint) 可根據 Unicode 标準識别字母。

  Character.isJavaIdentifierStart(int codePoint) 可根據 Java 語言規範确定代碼點是否可以啟動辨別符。

  Character.UnicodeBlock.of(int codePoint) 可搜尋代碼點所屬的 Unicode 字元子集。

  Character.toUpperCase(int codePoint) 可将給定的代碼點轉換為其大寫等值字元。盡管此方法能夠支援增補字元,但是它仍然不能解決根本的問題,即在某些情況下,逐個字元的轉換無法正确完成。例如,德文字元“"ß"”應該轉換為“SS”,這需要使用 String.toUpperCase 方法。

  注意大多數接受代碼點的方法并不檢查給定的 int 值是否處于有效的 Unicode 代碼點範圍之内(如上所述,隻有 0x0 至 0x10FFFF 之間的範圍是有效的)。在大多數情況下,該值是以確定其有效的方法産生的,在這些低層 API 中反複檢查其有效性可能會對系統性能造成負面的影響。在無法確定有效性的情況下,應用程式必須使用 Character.isValidCodePoint 方法確定代碼點有效。大多數方法對于無效的代碼點采取的行為沒有特别加以指定,不同的實作可能會有所不同。

  API 包含許多簡便的方法,這些方法可使用其他低層的 API 實作,但是專家組覺得,這些方法很常用,将它們添加到 J2SE 平台上很有意義。不過,專家組也排除了一些建議的簡便方法,這給我們提供了一次展示自己實作此類方法能力的機會。例如,專家組經過讨論,排除了一種針對 String 類的新建構器(該建構器可以建立一個保持單個代碼點的 String)。以下是使應用程式使用現有的 API 提供功能的一種簡便方法:

  String newString(int codePoint) {

  return new String(Character.toChars(codePoint));

  }

  您會注意到,在這個簡單的實作中,toChars 方法始終建立一個中間數列,該數列僅使用一次即立即丢棄。如果該方法在您的性能評估中出現,您可能會希望将其優化為針對最為普通的情況,即該代碼點為 BMP 字元:

  String newString(int codePoint) {

  if (Character.charCount(codePoint) == 1) {

  return String.valueOf((char) codePoint);

  } else {

  return new String(Character.toChars(codePoint));

  }

  }

  或者,如果您需要建立許多個這樣的 string,則可能希望編寫一個重複使用 toChars 方法所使用的數列的通用版本:

  String[] newStrings(int[] codePoints) {

  String[] result = new String[codePoints.length];

  char[] codeUnits = new char[2];

  for (int i = 0; i < codePoints.length; i++) {

  int count = Character.toChars(codePoints[i], codeUnits, 0);

  result[i] = new String(codeUnits, 0, count);

  }

  return result;

  }

  不過,最終您可能會發現,您需要的是一個完全不同的解決方案。新的建構器 String(int codePoint) 實際上建議作為 String.valueOf(char) 的一個基于代碼點的備選方案。在很多情況下,此方法用于消息生成的環境,例如:

  System.out.println("Character " + String.valueOf(char) + " is invalid.");

  新的Java.sun.com/j2se/1.5.0/docs/api/Java/util/formatter.hTMl" />格式化 API 支援增補文字,提供一種更加簡單的備選方案:

  System.out.printf("Character %c is invalid.%n", codePoint);

  使用此高層 API 不僅簡捷,而它有很多特殊的優點:它可以避免串聯(串聯會使消息很難本地化),并将需要移進資源包 (resource bundle) 的字元串數量從兩個減少到一個。

  增補字元透視:功能增強

  在支援使用增補字元的 Java 2 平台中的大部分更改沒有反映到新的 API 内。一般預期是,處理字元序列的所有接口将以适合其功能的方式處理增補字元。本部分着重講述為達到此預期所作一些功能增強。

  Java 程式設計語言中的辨別符

  Java 語言規範指出所有 Unicode 字母和數字均可用于辨別符。許多增補字元是字母或數字,是以 Java 語言規範已經參照新的基于代碼點的方法進行更新,以在辨別符内定義合法字元。為使用這些新方法,需要檢測辨別符的 Javac 編譯器和其他工具都進行了修訂。

  庫内的增補字元支援

  許多 J2SE 庫已經過增強,可以通過現有接口支援增補字元。以下是一些例子:

  字元串大小寫轉換功能已更新,可以處理增補字元,也可以實作 Unicode 标準中規定的特殊大小寫規則。

  Java.util.regex 包已更新,這樣模式字元串和目标字元串均可以包含增補字元并将其作為完整單元處理。

  現在,在 Java.text 包内進行整理處理時,會将增補字元看作完整單元。

  Java.text.Bidi 類已更新,可以處理增補字元和 Unicode 4.0 中新增的其他字元。請注意,Cypriot Syllabary 字元子集内的增補字元具有從右至左的方向性。

  Java 2D API 内的字型渲染和列印技術已經過增強,可以正确渲染和測量包含增補字元的字元串。

  Swing 文本元件實作已更新,可以處理包含增補字元的文本。

  字元轉換

  隻有很少的字元編碼可以表示增補字元。如果是基于 Unicode 的編碼(如 UTF-8 和 UTF-16LE),則舊版的 J2RE 内的字元轉換器已經按照正确處理增補字元的方式實作轉換。對于 J2RE 1.5,可以表示增補字元的其他編碼的轉換器已更新:GB18030、x-EUC-TW(現在實作所有 CNS 11643 層面)和 Big5-HKSCS(現在實作 HKSCS-2001)。

  在源檔案内表示增補字元

  在 Java 程式設計語言源檔案中,如果使用可以直接表示增補字元的字元編碼,則使用增補字元最為友善。UTF-8 是最佳的選擇。在所使用的字元編碼無法直接表示字元的情況下,Java 程式設計語言提供一種 Unicode 轉義符文法。此文法沒有經過增強,無法直接表示增補字元。而是使用兩個連續的 Unicode 轉義符将其表示為 UTF-16 字元表示法中的兩個編碼單元。例如,字元 U+20000 寫作“/uD840/uDC00”。您也許不願意探究這些轉義序列的含義;最好是寫入支援所需增補字元的編碼,然後使用一種工具(如 native2ascii)将其轉換為轉義序列。

  遺憾的是,由于其編碼問題,屬性檔案仍局限于 ISO 8859-1(除非您的應用程式使用新的 XML 格式)。這意味着您始終必須對增補字元使用轉義序列,而且可能要使用不同的編碼進行編寫,然後使用諸如 native2ascii 的工具進行轉換。

  經修訂的 UTF-8

  Java 平台對經修訂的 UTF-8 已經很熟悉,但是,問題是應用程式開發人員在可能包含增補字元的文本和 UTF-8 之間進行轉換時需要更加留神。需要特别注意的是,某些 J2SE 接口使用的編碼與 UTF-8 相似但與其并不相容。以前,此編碼有時被稱為“Java modified UTF-8”(經 Java 修訂的 UTF-8) 或(錯誤地)直接稱為“UTF-8”。對于 J2SE 1.5,其說明文檔正在更新,此編碼将統稱為“modified UTF-8”(經修訂的 UTF-8)。

  經修訂的 UTF-8 和标準 UTF-8 之間之是以不相容,其原因有兩點。其一,經修訂的 UTF-8 将字元 U+0000 表示為雙位元組序列 0xC0 0x80,而标準 UTF-8 使用單位元組值 0x0。其二,經修訂的 UTF-8 通過對其 UTF-16 表示法的兩個代理代碼單元單獨進行編碼表示增補字元 。每個代理代碼單元由三個位元組來表示,共有六個位元組。而标準 UTF-8 使用單個四位元組序清單示整個字元。

  Java 虛拟機及其附帶的接口(如 Java 本機接口、多種工具接口或 Java 類檔案)在 Java.io.DataInput 和 DataOutput 接口和類中使用經修訂的 UTF-8 實作或使用這些接口和類 ,并進行序列化。Java 本機接口提供與經修訂的 UTF-8 之間進行轉換的例程。而标準 UTF-8 由 String 類、Java.io.InputStreamReader 和 OutputStreamWriter 類、Java.nio.charset 設施 (facility) 以及許多其上層的 API 提供支援。

  由于經修訂的 UTF-8 與标準的 UTF-8 不相容,是以切勿同時使用這兩種版本的編碼。經修訂的 UTF-8 隻能與上述的 Java 接口配合使用。在任何其他情況下,尤其對于可能來自非基于 Java 平台的軟體的或可能通過其編譯的資料流,必須使用标準的 UTF-8。需要使用标準的 UTF-8 時,則不能使用 Java 本機接口例程與經修訂的 UTF-8 進行轉換。

  在應用程式内支援增補字元

  現在,對大多數讀者來說最為重要的問題是:必須對應用程式進行哪些更改才能支援增補字元?

  答案取決于在應用程式中進行哪種類型的文本處理和使用哪些 Java 平台 API。

  對于僅以各種形式 char 序列([char[]、Java.lang.CharSequence 實作、Java.text.CharacterIterator 實作)處理文本和僅使用接受和退回序列(如 char 序列)的 Java API 的應用程式,可能根本不需要進行任何更改。Java 平台 API 的實作應該能夠處理增補字元。

  對于本身解釋單個字元、将單個字元傳送給 Java 平台 API 或調用能夠傳回單個字元的方法的應用程式,則需要考慮這些字元的有效值。在很多情況下,往往不要求支援增補字元。例如,如果某應用程式搜尋 char 序列中的 HTML 标記,并逐一檢查每個 char,它會知道這些标記僅使用 Basic Latin 字元子集中的字元。如果所搜尋的文本含有增補字元,則這些字元不會與标記字元混淆,因為 UTF-16 使用代碼單元表示增補字元,而代碼單元的值不會用于 BMP 字元。

  隻有在某應用程式本身解釋單個字元、将單個字元傳送給 Java 平台 API 或調用能夠傳回單個字元的方法且這些字元可能為增補字元時,才必須更改該應用程式。在提供使用 char 序列的并行 API 時,最好轉而使用此類 API。在其他情況下,有必要使用新的 API 在 char 和基于代碼點的表示法之間進行轉換,并調用基于代碼點的 API。當然,如果您發現在 J2SE 1.5 中有更新、更友善的 API,使您能夠支援增補字元并同時簡化代碼(如上 TMl/2004-05-26/character.hTMl#code5" />格式化範例 中所述),則沒有必要這樣做。

  您可能會猶豫,是将所有文本轉換為代碼點表示法(即 int[])然後在該表示法中處理,還是在大多數情況下仍采用 char 序列,僅在需要時轉換為代碼點,兩者之間孰優孰劣很難确定。當然,總體來說,Java 平台 API 相對于 char 序列肯定具有一定的優勢,而且采用 Java 平台 API 可以節省記憶體空間。

  對于需要與 UTF-8 之間進行轉換的應用程式,還需要認真考慮是需要标準的 UTF-8 還是經修訂的 UTF-8,并針對每種 UTF-8 采用适當的 Java 平台。“經修訂的 UTF-8”部分介紹進行正确選擇所需的資訊。

  使用增補字元測試應用程式

  經過前面部分的介紹後,無論您是否需要修訂應用程式,測試應用程式是否運作正常始終是一種正确的做法。對于不含有圖形使用者界面的應用程式,有關“TMl/2004-05-26/character.hTMl#source" />在源檔案内表示增補字元” 的資訊有助于設計測試用例。以下是有關使用圖形使用者界面進行測試的補充資訊。

  對于文本輸入,Java.sun.com/j2se/1.5.0/download.jsp" />Java 2 SDK 提供用于接受“/Uxxxxxx”格式字元串的代碼點輸入方法,這裡大寫的“U”表示轉義序列包含六個十六進制數字,是以允許使用增補字元。小寫的“u”表示轉義序列“/uxxxx”的原始格式。您可以在 J2SDK 目錄 demo/jfc/CodePointIM 内找到此輸入方法及其說明文檔(從 J2SE 1.5.0 Beta 2 版本開始)。

  對于字型渲染,您需要至少能夠渲染一些增補字元的字型。其中一種此類字型為 James Kass 的 TM" />Code2001 字型,它提供手寫體字形(如 Deseret 和 Old Italic)。利用 Java 2D 庫中提供新功能,您隻需将該字型安裝到 J2RE 的 lib/fonts/fallback 目錄内即可,然後它可自動添加至在 2D 和 XAWT 渲染時使用的所有邏輯字型 — 無需編輯字型配置檔案。

  至此,您就可以确認,您的應用程式能夠完全支援增補字元了!

  結論

  對增補字元的支援已經引入 Java 平台,大部分應用程式無需更改代碼即可處理這些字元。解釋單個字元的應用程式可以在 Character 類和多種 CharSequence 子類中使用基于代碼點的新 API。

  鳴謝

  Java 平台中的增補字元支援由 Java Community Process 的 JSR-204 專家組設計。技術規範設計主持為 Masayoshi Okutsu 和 Brian Beck (Sun Microsystems),其他專家組成員有 Craig Cummings (Oracle)、Mark Davis (IBM)、Markus Eble (SAP AG)、Jere Käpyaho (Nokia Corp.)、Kazuhiro Kazama (NTT)、Kenji Kazumura (Fujitsu Limited)、Eiichi Kimura (NEC Corp.)、Changshin Lee (TMax Soft Inc.) 和 Toshiki Murata (Oki Electric Industry Co.)。參考實作由 Sun Microsystems 的 Java Internationalization 團隊完成,并承蒙位于聖何塞的 IBM Globalization Center of Competency 的協助。技術規範的技術相容套件為 Java Compatibility Kit,由 Sun Microsystems 的 JCK 團隊實作。

  參考書目

  Masayoshi Okutsu, Brian Beck (ed.): Java/communityprocess/review/jsr204/index.hTMl" />Unicode Supplementary Character Support. Public Review Draft. Sun Microsystems, 2004.

  Java.sun.com/j2se/1.5.0/docs/api/index.hTMl" />Java 2 Platform, Standard Edition, v 1.5.0 API Specification. Sun Microsystems, 2004.

  The Unicode Consortium: The Unicode Standard, Version 4.0. Addison-Wesley, 2003.

  Ken Whistler, Mark Davis: TMl" />Character Encoding Model. Unicode Technical Report #17. The Unicode Consortium, 2000.

  James Kass: TM" />Code2001, a Plane 1 Unicode-based Font.

  關于作者

  Norbert Lindenberg 是 Sun Microsystems 的 Java Web Services 團隊内 Java Internationalization 技術主管。在加盟 Sun 之前,曾經供職于 General Magic 和 Apple Computer,參與過多個國際化項目。他畢業于德國的卡爾斯魯厄大學,擁有計算機科學理科碩士學位。

  Masayoshi Okutsu 是 Sun Microsystems 的 Java Web Services 團隊的一名國際化工程師,目前擔任 Unicode Supplementary Character Support 的 Java Specification Request 204 的技術規範主管。在加盟 Sun Microsystems 之前,供職于 Digital Equipment Corporation,期間曾經參與多個國際化項目。他畢業于日本山形大學,擁有電子

<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script> <script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>