UTF-16分为2个字符

时间:2015-08-02 11:27:59

标签: java encoding character-encoding utf-16

我一直认为java使用UTF-16在内部对其字符进行编码。事实证明,它使用u+xxxx格式来表示字符代码,并使用16位来存储char

但有时UTF-16需要超过2个字节。在这种情况下,java需要2个char来代表1 UTF-16个字符。

旁注:这让我想知道是否更正确的说“java只支持Unicode字符集,并使用16位单元格存储字符”

问题:第一个char是否提供了一些方法来确定是使用了第二个char,还是2个属于一起?

1 个答案:

答案 0 :(得分:6)

是的,UTF-16是在Unicode扩展时将Unicode 1.0的65536代码点限制传递到今天的1114112代码点限制时发明的。

这使它能够支持整个通用字符集,同时保持与UCS-2的兼容性;所有Unicode字符的过时编码为双字节单位,因为它无法在Unicode 2.0或更高版本中对所有Unicode字符进行编码,因此已过时。

  

第一个char是否提供了一些方法来确定是否使用了第二个char,或者2是否属于一个?

是的,在UTF-16中,两个字节的单位是:

  1. 一个高代理人,必须始终跟一个低代理人。在0xD8000xDBFF之间,isHighSurrogate将返回true
  2. 低代理人必须始终遵循高代理人。在0xDC000xDFFF之间,isLowSurrogate将返回true
  3. 非代理人。
  4. 非代理地图直接使用相同代码点的BMP字符。

    代理人结合起来代表星体平面人物:

    1. 从代码点减去0x010000。
    2. 将前10位添加到0xD800以获得高代理。
    3. 将低10位添加到0xDC00以获得低代理。
    4. 在Java中,您可以首先使用代码点检查isBmpCodePoint上的int。如果这是真的,那么你可以将其转换为char以获得编码它的单个UTF-16单元。否则,您可以致电highSurrogate获取第一个charlowSurrogate以获得第二个。

      isBmpCodePoint一样,您可以使用charCount返回1表示BMP字符,2表示您需要代理。如果您要创建一个包含12个字符的数组来保存该值,这将非常有用。

      由于代理代码点永远不会被分配字符,这意味着整个通用字符集的编码是明确的。

      它也是自我纠正,流中的错误可以被隔离,而不是导致所有其他字符被误读。例如。如果我们找到一个孤立的低代理,我们知道该位是错误的,但仍然可以读取流的其余部分。

      一些完整的例子,但我不是太热了Java(另一方面,我知道的是Unicode,这是我用来回答这个问题的知识),所以如果有人发现了一个n00b Java错误,但我认为我得到了Unicode知识部分是正确的,请继续相应地编辑这篇文章:

      ""是一个带有单个Unicode字符的字符串,U+10300是旧斜体字母的一个字母。在大多数情况下,这些“Astral Planes”角色因为半开玩笑而被称为相对模糊,因为Unicode联盟试图尽可能地使用它们而不会超出易于使用的BMP(基本多语言平面; { {1}}至U+0000,但有时列为“U+FFFFU+0000 U+FFFDU+FFFE均为非字符,不应使用在大多数情况下)。

      (如果你正在尝试这个,那么直接使用U+FFFF的那些将取决于你的文本编辑器应对它的程度)。

      如果您检查,您将获得"".length,因为2会为您提供UTF-16编码单位的数量,而不是字符数。

      length应该返回new StringBuilder().appendCodePoint(0x10300).toString() == ""

      true将返回Character.charCount(0x10300),因为我们需要两个UTF-16 2来对其进行编码。 char将返回Character.isBmpCodePoint(0x10300)

      false将返回Character.codePointAt("", 0) 66304,因为当它看到高代理时,它会在计算中读取以下低代理值。

      0x10300是正确的,因为那些是高和低代理人,角色应该被拆分成UTF-16编码。

      同样Character.highSurrogate(0x10300) == 0xD800 && Character.lowSurrogate(0x10300) == 0xDF00因为"".charAt(0) == 0xD800 && "".charAt(1) == 0xDF00处理的是UTF-16单位,而不是Unicode字符。

      使用相同的符号charAt为两个代理人使用转义符。