`
NanguoCoffee
  • 浏览: 51690 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

[转]Java 平台中的增补字符

阅读更多

本文转自:http://java.sun.com/developer/technicalArticles/Intl/Supplementary/index_zh_CN.html

 

Article

Java 平台中的增补字符

 

2004 年 5 月

English: Supplementary Characters in the Java Platform
日本語: Java プラットフォームにおける補助文字のサポート

摘要

本文介绍 Java 平台支持增补字符的方式。增补字符是 Unicode 标准中代码点超出 U+FFFF 的字符,因此它们无法在 Java 编程语言中描述为单个的 16 位实体(例如 char  数据类型)。这些字符一般极少用,但是,有些会在诸如中文或日文人名中用到,因此,在东亚国家,政府应用程序通常会要求支持这些字符。

Java 平台目前正在改进,以便支持对增补字符的处理,这种改进对现有的应用程序影响微乎其微。新的低层 API 在需要时能够使用单个的字符运行。不过,大多数文本处理 API 均使用字符序列,例如String  类或字符数组。现在,这些均解释为 UTF-16 序列,而且,这些 API 实现已转变为正确地处理增补字符。这些改进已融入 Java 2 平台 5.0 版,标准版 (J2SE)。

除详细解释这些改进之外,本文同时为应用程序开发人员确定和实现必要的更改提供指导,以支持整个 Unicode 字符集的使用。

背景

Unicode 最初设计是作为一种固定宽度的 16 位字符编码。在 Java 编程语言中,基本数据类型 char  初衷是通过提供一种简单的、能够包含任何字符的数据类型来充分利用这种设计的优点。不过,现在看来,16 位编码的所有 65,536 个字符并不能完全表示全世界所有正在使用或曾经使用的字符。于是,Unicode 标准已扩展到包含多达 1,112,064 个字符。那些超出原来的 16 位限制的字符被称作增补字符。Unicode 标准 2.0 版是第一个包含启用增补字符设计的版本,但是,直到 3.1 版才收入第一批增补字符集。由于 J2SE 的 5.0 版必须支持 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“字符编码模型 ”。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 代码点 U+0041 U+00DF U+6771 U+10400
表示字形
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 虚拟机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(char high, char low) (用于将两个 UTF-16 代码单元转换为一个代码点)和 Character.toChars(int codePoint) (用于将指定的代码点转换为一个或两个 UTF-16 代码单元,然后封装到一个 char[]  内。不过,由于大多数情况下文本以字符序列的形式出现,因此,另外提供 codePointAt  和 codePointBefore  方法,用于将代码点从各种字符序列表示法中提取出来:Character.codePointAt(char[] a, int index)  和 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。
 */
String newString(int codePoint) {
    return new String(Character.toChars(codePoint));
}

您会注意到,在这个简单的实现中,toChars  方法始终创建一个中间数列,该数列仅使用一次即立即丢弃。如果该方法在您的性能评估中出现,您可能会希望将其优化为针对最为普通的情况,即该代码点为 BMP 字符:


/**
 * 创建仅含有指定代码点的新 String。
 * 针对 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。
 * 针对 BMP 字符优化的版本。
 */
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.");

新的格式化 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 5.0,可以表示增补字符的其他编码的转换器已更新: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 5.0,其说明文档正在更新,此编码将统称为“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 5.0 中有更新、更方便的 API,使您能够支持增补字符并同时简化代码(如上 格式化范例  中所述),则没有必要这样做。

您可能会犹豫,是将所有文本转换为代码点表示法(即 int[] )然后在该表示法中处理,还是在大多数情况下仍采用 char  序列,仅在需要时转换为代码点,两者之间孰优孰劣很难确定。当然,总体来说,Java 平台 API 相对于 char  序列肯定具有一定的优势,而且采用 Java 平台 API 可以节省内存空间。

对于需要与 UTF-8 之间进行转换的应用程序,还需要认真考虑是需要标准的 UTF-8 还是经修订的 UTF-8,并针对每种 UTF-8 采用适当的 Java 平台。“经修订的 UTF-8 ”部分介绍进行正确选择所需的信息。

使用增补字符测试应用程序

经过前面部分的介绍后,无论您是否需要修订应用程序,测试应用程序是否运行正常始终是一种正确的做法。对于不含有图形用户界面的应用程序,有关“在源文件内表示增补字符 ” 的信息有助于设计测试用例。以下是有关使用图形用户界面进行测试的补充信息。

对于文本输入,Java 2 SDK  提供用于接受“\Uxxxxxx”格式字符串的代码点输入方法,这里大写的“U”表示转义序列包含六个十六进制数字,因此允许使用增补字符。小写的“u”表示转义序列“\uxxxx”的原始格式。您可以在 J2SDK 目录 demo/jfc/CodePointIM 内找到此输入方法及其说明文档。

对于字体渲染,您需要至少能够渲染一些增补字符的字体。其中一种此类字体为 James Kass 的 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.): Unicode Supplementary Character Support. Proposed Final Draft . Sun Microsystems, 2004.

Java 2 Platform Standard Edition 5.0 API Specification . Sun Microsystems, 2004.

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

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

James Kass: 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,期间曾经参与多个国际化项目。他毕业于日本山形大学,拥有电子工程理学士学位。

 



1  本网站中使用的术语“Java 虚拟机”或“JVM”是指针对 Java 平台的虚拟机。

 

 


分享到:
评论

相关推荐

    智能车竞赛介绍(竞赛目标和赛程安排).zip

    全国大学生智能汽车竞赛自2006年起,由教育部高等教育司委托高等学校自动化类教学指导委员会举办,旨在加强学生实践、创新能力和培养团队精神的一项创意性科技竞赛。该竞赛至今已成功举办多届,吸引了众多高校学生的积极参与,此文件为智能车竞赛介绍

    集字卡v4.3.4微信公众号原版三种UI+关键字卡控制+支持强制关注.zip

    字卡v4.3.4 原版 三种UI+关键字卡控制+支持获取用户信息+支持强制关注 集卡模块从一开始的版本到助力版本再到现在的新规则版本。 集卡模块难度主要在于 如何控制各种不同的字卡组合 被粉丝集齐的数量。 如果不控制那么一定会出现超过数量的粉丝集到指定的字卡组合,造成奖品不够的混乱,如果大奖价值高的话,超过数量的粉丝集到大奖后,就造成商家的活动费用超支了。我们冥思苦想如何才能限制集到指定字卡组合的粉丝数,后我们想到了和支付宝一样的选一张关键字卡来进行规则设置的方式来进行限制,根据奖品所需的关键字卡数,设定规则就可以控制每种奖品所需字卡组合被粉丝集到的数量,规则可以在活动进行中根据需要进行修改,活动规则灵活度高。新版的集卡规则,在此次政府发布号的活动中经受了考验,集到指定字卡组合的粉丝没有超出规则限制。有了这个规则限制后,您无需盯着活动,建好活动后就无人值守让活动进行就行了,您只需要时不时来看下蹭蹭上涨的活动数据即可。 被封? 无需担心,模块内置有防封功能,支持隐藏主域名,显示炮灰域名,保护活动安全进行。 活动准备? 只需要您有一个认证服务号即可,支持订阅号借用认证服务号来做活动。如果您

    出口设备线体程序详解:PLC通讯下的V90控制与开源FB284工艺对象实战指南,出口设备线体程序详解:PLC通讯与V90控制集成,工艺对象与FB284协同工作,开源学习V90控制技能,出口设备1200

    出口设备线体程序详解:PLC通讯下的V90控制与开源FB284工艺对象实战指南,出口设备线体程序详解:PLC通讯与V90控制集成,工艺对象与FB284协同工作,开源学习V90控制技能,出口设备1200线体程序,多个plc走通讯,内部有多个v90,采用工艺对象与fb284 共同控制,功能快全部开源,能快速学会v90的控制 ,出口设备; 1200线体程序; PLC通讯; 多个V90; 工艺对象; FB284; 功能开源; V90控制。,V90工艺控制:开源功能快,快速掌握1200线体程序与PLC通讯

    基于Arduino与DAC8031的心电信号模拟器资料:心电信号与正弦波的双重输出应用方案,Arduino与DAC8031心电信号模拟器:生成心电信号与正弦波输出功能详解,基于arduino +DAC

    基于Arduino与DAC8031的心电信号模拟器资料:心电信号与正弦波的双重输出应用方案,Arduino与DAC8031心电信号模拟器:生成心电信号与正弦波输出功能详解,基于arduino +DAC8031的心电信号模拟器资料,可输出心电信号,和正弦波 ,基于Arduino;DAC8031;心电信号模拟器;输出心电信号;正弦波输出;模拟器资料,基于Arduino与DAC8031的心电信号模拟器:输出心电与正弦波

    (参考项目)MATLAB口罩识别检测.zip

    MATLAB口罩检测的基本流程 图像采集:通过摄像头或其他图像采集设备获取包含面部的图像。 图像预处理:对采集到的图像进行灰度化、去噪、直方图均衡化等预处理操作,以提高图像质量,便于后续的人脸检测和口罩检测。 人脸检测:利用Haar特征、LBP特征等经典方法或深度学习模型(如MTCNN、FaceBoxes等)在预处理后的图像中定位人脸区域。 口罩检测:在检测到的人脸区域内,进一步分析是否佩戴口罩。这可以通过检测口罩的边缘、纹理等特征,或使用已经训练好的口罩检测模型来实现。 结果输出:将检测结果以可视化方式展示,如在图像上标注人脸和口罩区域,或输出文字提示是否佩戴口罩。

    kernel-debug-devel-3.10.0-1160.119.1.el7.x64-86.rpm.tar.gz

    1、文件内容:kernel-debug-devel-3.10.0-1160.119.1.el7.rpm以及相关依赖 2、文件形式:tar.gz压缩包 3、安装指令: #Step1、解压 tar -zxvf /mnt/data/output/kernel-debug-devel-3.10.0-1160.119.1.el7.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm 4、更多资源/技术支持:公众号禅静编程坊

    day02供应链管理系统-补充.zip

    该文档提供了一个关于供应链管理系统开发的详细指南,重点介绍了项目安排、技术实现和框架搭建的相关内容。 文档分为以下几个关键部分: 项目安排:主要步骤包括搭建框架(1天),基础数据模块和权限管理(4天),以及应收应付和销售管理(5天)。 供应链概念:供应链系统的核心流程是通过采购商品放入仓库,并在销售时从仓库提取商品,涉及三个主要订单:采购订单、销售订单和调拨订单。 大数据的应用:介绍了数据挖掘、ETL(数据抽取)和BI(商业智能)在供应链管理中的应用。 技术实现:讲述了DAO(数据访问对象)的重用、服务层的重用、以及前端JS的继承机制、jQuery插件开发等技术细节。 系统框架搭建:包括Maven环境的配置、Web工程的创建、持久化类和映射文件的编写,以及Spring配置文件的实现。 DAO的需求和功能:供应链管理系统的各个模块都涉及分页查询、条件查询、删除、增加、修改操作等需求。 泛型的应用:通过示例说明了在Java语言中如何使用泛型来实现模块化和可扩展性。 文档非常技术导向,适合开发人员参考,用于构建供应链管理系统的架构和功能模块。

    基于四旋翼无人机的PD控制研究 附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    C#与VB实现欧姆龙PLC的Fins TCP通信案例源码:调用动态链接库进行数据读写,定时器与计数器数据区的简洁读写操作示例,C#与VB实现欧姆龙PLC的Fins TCP通信案例源码:调用动态链接库进

    C#与VB实现欧姆龙PLC的Fins TCP通信案例源码:调用动态链接库进行数据读写,定时器与计数器数据区的简洁读写操作示例,C#与VB实现欧姆龙PLC的Fins TCP通信案例源码:调用动态链接库进行读写操作,涵盖定时器计数器数据区学习案例,C#欧姆龙plc Fins Tcp通信案例上位机源码,有c#和VB的Demo,c#上位机和欧姆龙plc通讯案例源码,调用动态链接库,可以实现上位机的数据连接,可以简单实现D区W区定时器计数器等数据区的读写,是一个非常好的学习案例 ,C#; 欧姆龙PLC; Fins Tcp通信; 上位机源码; 动态链接库; 数据连接; D区W区读写; 定时器计数器; 学习案例,C#实现欧姆龙PLC Fins Tcp通信上位机源码,读写数据区高效学习案例

    可调谐石墨烯超材料吸收体的FDTD仿真模拟研究报告:吸收光谱的化学势调节策略与仿真源文件解析,可调谐石墨烯超材料吸收体:化学势调节光谱的FDTD仿真模拟研究,可调谐石墨烯超材料吸收体FDTD仿真模拟

    可调谐石墨烯超材料吸收体的FDTD仿真模拟研究报告:吸收光谱的化学势调节策略与仿真源文件解析,可调谐石墨烯超材料吸收体:化学势调节光谱的FDTD仿真模拟研究,可调谐石墨烯超材料吸收体FDTD仿真模拟 【案例内容】该案例提供了一种可调谐石墨烯超材料吸收体,其吸收光谱可以通过改变施加于石墨烯的化学势来进行调节。 【案例文件】仿真源文件 ,可调谐石墨烯超材料吸收体; FDTD仿真模拟; 化学势调节; 仿真源文件,石墨烯超材料吸收体:FDTD仿真调节吸收光谱案例解析

    RBF神经网络控制仿真-第二版

    RBF神经网络控制仿真-第二版

    松下PLC与威纶通触摸屏转盘设备控制:FPWINPRO7与EBPRO智能编程与宏指令应用,松下PLC与威纶通触摸屏转盘设备控制解决方案:FPWINPRO7与EBPRO协同工作,实现多工位转盘加工与IE

    松下PLC与威纶通触摸屏转盘设备控制:FPWINPRO7与EBPRO智能编程与宏指令应用,松下PLC与威纶通触摸屏转盘设备控制解决方案:FPWINPRO7与EBPRO协同工作,实现多工位转盘加工与IEC编程模式控制,松下PLC+威纶通触摸屏的转盘设备 松下PLC工程使用程序版本为FPWINPRO7 7.6.0.0版本 威纶通HMI工程使用程序版本为EBPRO 6.07.02.410S 1.多工位转盘加工控制。 2.国际标准IEC编程模式。 3.触摸屏宏指令应用控制。 ,松下PLC; 威纶通触摸屏; 转盘设备控制; 多工位加工控制; IEC编程模式; 触摸屏宏指令应用,松下PLC与威纶通HMI联控的转盘设备控制程序解析

    基于循环神经网络(RNN)的多输入单输出预测模型(适用于时间序列预测与回归分析,需Matlab 2021及以上版本),基于循环神经网络(RNN)的多输入单输出预测模型(matlab版本2021+),真

    基于循环神经网络(RNN)的多输入单输出预测模型(适用于时间序列预测与回归分析,需Matlab 2021及以上版本),基于循环神经网络(RNN)的多输入单输出预测模型(matlab版本2021+),真实值与预测值对比,多种评价指标与线性拟合展示。,RNN预测模型做多输入单输出预测模型,直接替数据就可以用。 程序语言是matlab,需求最低版本为2021及以上。 程序可以出真实值和预测值对比图,线性拟合图,可打印多种评价指标。 PS:以下效果图为测试数据的效果图,主要目的是为了显示程序运行可以出的结果图,具体预测效果以个人的具体数据为准。 2.由于每个人的数据都是独一无二的,因此无法做到可以任何人的数据直接替就可以得到自己满意的效果。 这段程序主要是一个基于循环神经网络(RNN)的预测模型。它的应用领域可以是时间序列预测、回归分析等。下面我将对程序的运行过程进行详细解释和分析。 首先,程序开始时清空环境变量、关闭图窗、清空变量和命令行。然后,通过xlsread函数导入数据,其中'数据的输入'和'数据的输出'是两个Excel文件的文件名。 接下来,程序对数据进行归一化处理。首先使用ma

    【图像识别】手写文字识别研究 附Matlab代码+运行结果.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    旅游管理系统(基于springboot,mysql,java).zip

    旅游管理系统中的功能模块主要是实现管理员;首页、个人中心、用户管理、旅游方案管理、旅游购买管理、系统管理,用户;首页、个人中心、旅游方案管理、旅游购买管理、我的收藏管理。前台首页;首页、旅游方案、旅游资讯、个人中心、后台管理等功能。经过认真细致的研究,精心准备和规划,最后测试成功,系统可以正常使用。分析功能调整与旅游管理系统实现的实际需求相结合,讨论了Java开发旅游管理系统的使用。 从上面的描述中可以基本可以实现软件的功能: 1、开发实现旅游管理系统的整个系统程序;  2、管理员;首页、个人中心、用户管理、旅游方案管理、旅游购买管理、系统管理等。 3、用户:首页、个人中心、旅游方案管理、旅游购买管理、我的收藏管理。 4、前台首页:首页、旅游方案、旅游资讯、个人中心、后台管理等相应操作; 5、基础数据管理:实现系统基本信息的添加、修改及删除等操作,并且根据需求进行交流查看及回复相应操作。

    Boost二级升压光伏并网结构的Simulink建模与MPPT最大功率点追踪:基于功率反馈的扰动观察法调整电压方向研究,Boost二级升压光伏并网结构的Simulink建模与MPPT最大功率点追踪:基

    Boost二级升压光伏并网结构的Simulink建模与MPPT最大功率点追踪:基于功率反馈的扰动观察法调整电压方向研究,Boost二级升压光伏并网结构的Simulink建模与MPPT最大功率点追踪:基于功率反馈的扰动观察法调整电压方向研究,Boost二级升压光伏并网结构,Simulink建模,MPPT最大功率点追踪,扰动观察法采用功率反馈方式,若ΔP>0,说明电压调整的方向正确,可以继续按原方向进行“干扰”;若ΔP<0,说明电压调整的方向错误,需要对“干扰”的方向进行改变。 ,Boost升压;光伏并网结构;Simulink建模;MPPT最大功率点追踪;扰动观察法;功率反馈;电压调整方向。,光伏并网结构中Boost升压MPPT控制策略的Simulink建模与功率反馈扰动观察法

    基于matlab平台的图像去雾设计.zip

    运行GUI版本,可二开

    Deepseek相关参考资源文档

    Deepseek相关主题资源及行业影响

    WP Smush Pro3.16.12 一款专为 WordPress 网站设计的图像优化插件开心版.zip

    WP Smush Pro 是一款专为 WordPress 网站设计的图像优化插件。 一、主要作用 图像压缩 它能够在不影响图像质量的前提下,大幅度减小图像文件的大小。例如,对于一些高分辨率的产品图片或者风景照片,它可以通过先进的压缩算法,去除图像中多余的数据。通常 JPEG 格式的图像经过压缩后,文件大小可以减少 40% – 70% 左右。这对于网站性能优化非常关键,因为较小的图像文件可以加快网站的加载速度。 该插件支持多种图像格式的压缩,包括 JPEG、PNG 和 GIF。对于 PNG 图像,它可以在保留透明度等关键特性的同时,有效地减小文件尺寸。对于 GIF 图像,也能在一定程度上优化文件大小,减少动画 GIF 的加载时间。 懒加载 WP Smush Pro 实现了图像懒加载功能。懒加载是一种延迟加载图像的技术,当用户滚动页面到包含图像的位置时,图像才会加载。这样可以避免一次性加载大量图像,尤其是在页面内容较多且包含许多图像的情况下。例如,在一个新闻网站的长文章页面,带有大量配图,懒加载可以让用户在浏览文章开头部分时,不需要等待所有图片加载,从而提高页面的初始加载速度,同时也能

    1. Download this file: https://cdn-media.huggingface.co/frpc-gradio-0.3/frpc-windows-amd64.exe

    Could not create share link. Missing file: C:\Users\xx\.conda\envs\omni\Lib\site-packages\gradio\frpc_windows_amd64_v0.3 1. Download this file: https://cdn-media.huggingface.co/frpc-gradio-0.3/frpc_windows_amd64.exe 2. Rename the downloaded file to: frpc_windows_amd64_v0.3 3. Move the file to this location: C:\Users\xx\.conda\envs\omni\Lib\site-packages\gradio

Global site tag (gtag.js) - Google Analytics