根据Java SE 7规范,Java使用Unicode UTF-16标准来表示字符。当将String
想象为16位变量的A 简单阵列每个字符时,生活很简单。
不幸的是,有16位根本不够的代码点(我相信这是所有Unicode字符的16/17)。因此,在String
中,这没有任何直接的问题,因为当想要使用添加两个字节存储这些〜1.048.576个字符之一时,只需使用两个数组位置即可使用String
。P>
这不带任何直接问题问题,适用于 String
s,因为总是有两个字节。尽管与单个变量相比,与UTF-16编码相比,其固定长度为16位 ,如何存储这些字符,尤其是Java如何使用它的 2字节" char"类型?
答案在Javadoc:
char数据类型(因此,字符对象的值 封装)基于原始Unicode规范,该规范 将字符定义为固定宽度16位实体。Unicode 此后已更改标准以允许字符 表示形式需要超过16位。
法律法规的范围 现在,点为u 0000到u 10ffff,称为Unicode标量值。 (请参阅Unicode标准中的U N符号的定义。) 有时会引用从u 0000到u ffff的字符集 作为基本的多语言平面(BMP)。代码点的字符 比U FFFF大称为补充字符。爪哇 2平台在char阵列中使用UTF-16表示形式 字符串和StringBuffer类。在此代表中,补充 字符被表示为一对char值,第一个来自 高弹药范围( ud800- udbff),第二个 低弹药范围( udc00- udfff)。
因此,一个字符值, 代表基本的多语言平面(BMP)代码点,包括 替代代码点或UTF-16编码的代码单位。一个int 值代表所有Unicode代码点,包括补充代码 点。较低(最低)21位int用于 表示Unicode代码点和上部(最重要的)11位 必须为零。
除非另有说明,否则 补充字符和替代字符值如下: 仅接受字符价值的方法无法支持补充 人物。他们将代孕范围的炭值视为 未定义的字符。例如,字符。 返回false,即使此特定值遵循任何特定值 字符串中的低溶剂值代表字母。方法 接受int值支持所有Unicode字符,包括 补充字符。例如,字符isletter(0x2f81a) 返回true是因为代码点值代表字母(cjk 表意文字)。在Java SE API文档中,Unicode代码点为 用于在u 0000和u 10ffff之间的字符值, 和Unicode代码单元用于16位char值(代码) UTF-16编码的单位。有关Unicode的更多信息 术语,请参阅Unicode词汇表。
简单地说:
- char规则的16位是为Unicode标准的旧版本设计的
- 有时您需要两个字符来表示不在基本多语言平面中的Unicode符文(代码点)。这种"工作"是因为您不经常使用字符,尤其是在BMP外处理Unicode。
更简单说:
- java char不代表Unicode Codepoint(嗯,并非总是)。
顺便说一句,可以指出的是,UNICODE延伸超过BMP使UTF-16无关紧要的演变,现在UTF-16甚至没有启用固定的字节键比。这就是为什么更多的现代语言基于UTF-8的原因。此宣言有助于理解它。
基本上,字符串存储了一系列UTF-16代码单元...它与存储Unicode代码点的序列并不相同。
当需要基本多语言平面以外的字符时,占用String
中的两个UTF-16代码单元。
大多数String
操作-length()
,charAt
,substring()
等交易UTF -16代码单元的数量。但是,有类似codePointAt()
的操作将处理完整的Unicode代码点...尽管索引仍以UTF-16代码单位表示。
编辑:如果要将非BMP代码点存储在单个char
中,那么您基本上是不幸的。这就像想在byte
变量中存储256多个不同的值一样……它不起作用。遵循代码点在其他地方表示代码的约定(例如在String
中),最好只使用int
变量。