在 Java 中使用表情符号进行字符串编码?

String Encoding with Emoji in Java?

我有这样的小测试例子

    public class Main {
        public static void main(String[] args) {
            String s = "";
            System.out.println(s);
            System.out.println(s.length());
            System.out.println(s.toCharArray().length);
            System.out.println(s.getBytes(StandardCharsets.UTF_8).length);
            System.out.println(s.getBytes(StandardCharsets.UTF_16).length);
            System.out.println(s.codePointCount(0, s.length()));
            System.out.println(Character.codePointCount(s, 0, s.length()));
       }
    }

结果是:


4
4
8
10
2
2

我不明白,为什么 1 个 unicode 字符瓦努阿图标志 return 长度为 4,在 utf-8 中为 8 个字节,在 utf-16 中为 10 个字节,我知道 java 使用 UTF-16 并且它需要 1 个字符(2 个字节)作为 1 个代码点,但它让我对 1 个 unicode 字符的 4 个字符感到困惑,我认为它只需要 2 个字符但结果为 4。有人可以充分解释以帮助我理解这一点.非常感谢。

Unicode 标志表情符号被编码为两个 个代码点。

有26个Regional Indicator Symbols代表A-Z,一个flag是通过拼写ISO国家代码来编码的。比如瓦努阿图国旗编码为“VU”,美国国旗编码为“US”。

指标都在补充平面上,所以每一个都需要两个UTF-16字符。这使每个旗帜的总数达到 4 Java char

这样做的目的是避免每当一个国家获得或失去独立时都必须更新标准,并且它有助于 Unicode 联盟保持中立,因为它不必成为地缘政治主张的仲裁者。

UTF-8 是一种 variable-length 编码,每个 Unicode 字符使用 1 到 4 个字节。第一个字节包含字符的 3 到 7 位,每个后续字节包含 6 位。因此有 7 到 21 位的有效载荷。

所需字节数取决于特定字符。

编码见this Wikipedia page

UTF-16 对一个 Unicode 字符使用一个 16 位单元或两个 16 位单元。大致来说,前64K个字符中的字符被编码为一个单元;超出该范围的字符需要两个单位。

“大约”,因为实际上,适合一个16位单元的代码要么在U+0000到U+D7FF,要么在U+E000到U+FFFF。这两者之间的值用于 two-unit 格式。

所需的 16 位单元数取决于特定字符。

参见this other Wikipedia page