问题描述
我有像这样的小型测试示例
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,s.length()));
}
}
结果是:
??
4
4
8
10
2
2
我不明白,为什么1个Unicode字符Vanuatu标志返回4个长度,utf-8中为8个字节,utf-16中为10个字节,我知道使用Java UTF-16,它需要1个代码点使用1个字符(2个字节),但它使我对1个Unicode字符的4个字符感到困惑,我认为它只需要2个字符但结果为4。有人可以充分解释以帮助我理解这一点。 。非常感谢。
解决方法
Unicode标志表情符号被编码为两个代码点。
有26个Regional Indicator Symbols代表A-Z,并且通过拼写ISO国家/地区代码对标记进行编码。例如,瓦努阿图标志被编码为“ VU”,美国标志被编码为“ US”。
这些指示器全部在补充平面上,因此它们每个都需要两个UTF-16字符。这样一来,每个标志的总数就多达4个Java char
。
这样做的目的是避免在一个国家获得或失去独立性时就不必更新标准,并且它可以帮助Unicode联盟保持中立,因为它不必成为地缘政治主张的仲裁者。
,UTF-8是一种可变长度编码,每个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。这两个之间的值用于两个单位的格式。
所需的16位单元数取决于特定字符。