gpt4 book ai didi

java - UTF-16 分成 2 个字符

转载 作者:行者123 更新时间:2023-12-02 06:56:53 29 4
gpt4 key购买 nike

我一直相信java使用UTF-16在内部对其字符进行编码。它使用 u+xxxx 的事实证实了这一点。表示字符代码的格式以及它使用 16 位存储 char 的事实。 .

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

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

问题:是否第一个char提供一些方法来确定第二个 char是用的,还是说这两个属于一起?

最佳答案

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

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

Does the first char offer some method to determine that a second char is used, or that the 2 belong together?



是的,在 UTF-16 中,两个字节的单位是:
  • 高代理,必须始终跟随低代理。在 0xD8000xDBFF 之间,isHighSurrogate 将返回 true
  • 必须始终遵循高代理的低代理。在 0xDC000xDFFF 之间,isLowSurrogate 将返回 true
  • 非代理。

  • 非代理映射直接使用相同代码点的 BMP 字符。

    代理组合来代表星界字符:
  • 从代码点中减去 0x010000。
  • 将前 10 位添加到 0xD800 以获得高代理。
  • 将低 10 位添加到 0xDC00 以获得低代理。

  • 在 Java 中,您可以通过首先使用代码点检查 isBmpCodePoint 上的 int 来完成此操作。如果这是真的,那么您只需将其转换为 char 即可获得对其进行编码的单个 UTF-16 单元。否则你可以调用 highSurrogate 来获取第一个 charlowSurrogate 来获取第二个。

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

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

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

    一些完整的例子,但我对 Java 不太感兴趣(另一方面,Unicode,我很清楚,这就是我用来回答这个问题的知识),所以如果有人发现 n00b Java 错误但认为我得到了 Unicode-知识部分正确,请继续并相应地编辑这篇文章:
    "𐌞" 是一个带有单个 Unicode 字符的字符串, U+10300 是旧斜体字母表中的一个字母。在大多数情况下,这些被半开玩笑地称为“星界”的字符相对晦涩,因为 Unicode 联盟试图在不脱离更易于使用的 BMP(基本多语言平面; U+0000)的情况下尽可能地发挥作用到 U+FFFF ,虽然有时被列为“ U+0000U+FFFD 作为 U+FFFEU+FFFF 都是非字符,在大多数情况下不应该使用)。

    (如果你正在试验这个,那么那些直接使用 𐌞 的将取决于你的文本编辑器处理它的程度)。

    如果您检查 "𐌞".length,您将得到 2,因为 length 为您提供 UTF-16 编码单元的数量,而不是字符的数量。
    new StringBuilder().appendCodePoint(0x10300).toString() == "𐌞" 应该返回 true
    Character.charCount(0x10300) 将返回 2 因为我们需要两个 UTF-16 char 对其进行编码。 Character.isBmpCodePoint(0x10300) 将返回 false
    Character.codePointAt("𐌞", 0) 将返回 66304 ,即 0x10300 ,因为当它看到高代理时,它会在计算中读取以下低代理。
    Character.highSurrogate(0x10300) == 0xD800 && Character.lowSurrogate(0x10300) == 0xDF00 是正确的,因为这些是字符应该被拆分为以 UTF-16 编码的高和低代理。

    同样 "𐌞".charAt(0) == 0xD800 && "𐌞".charAt(1) == 0xDF00 因为 charAt 处理 UTF-16 单元,而不是 Unicode 字符。

    出于同样的原因, "𐌞" == "\uD800\uDF00" 对两个代理使用转义。

    关于java - UTF-16 分成 2 个字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31771427/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com