这一切都是一个非常基本的问题:给定char
- 或者更确切地说,整数代码点,请参阅Character
API - ,返回其UTF-8编码所需的字节数。然而,我花在这个无辜的小问题上的时间越多,它变得越混乱。
我的第一个方法是:
int getUtf8ByteCount_stdlib(int codePoint) {
int[] codePoints = { codePoint };
String string = new String(codePoints, 0, 1);
byte[] bytes = string.getBytes(StandardCharsets.UTF_8);
return bytes.length;
}
或者喜欢它的人:
int getUtf8ByteCount_obfuscated(int codePoint) {
return new String(new int[] { codePoint }, 0, 1).getBytes(StandardCharsets.UTF_8).length;
}
然后我创建了另一个版本(基于UTF-8 wikipedia article),以简化和提高效率:
int getUtf8ByteCount_handRolled(int codePoint) {
if (codePoint > 0x7FFFFFFF) {
throw new IllegalArgumentException("invalid UTF-8 code point");
}
return codePoint <= 0x7F? 1
: codePoint <= 0x7FF? 2
: codePoint <= 0xFFFF? 3
: codePoint <= 0x1FFFFF? 4
: codePoint <= 0x3FFFFFF? 5
: 6;
}
经过多年努力与字符编码的许多可爱的微妙之处,我跑了一个测试,然后!它失败了;对于来自&#39; \ uD800&#39;的所有代码点&#39; \ uDFFF&#39;,&#34; stdlib&#34;版本返回1个字节而3个字节用于&#34;手动滚动&#34;。当然,这是好事。代理人物再次造成破坏!现在,根据我对那些讨厌的小虫子的理解,我会说第二个版本是正确的。我的问题:
String.getBytes()
还是(Java的UTF-8实施)被破坏了,还是我的理解? (我使用的是Oracle Java SE Runtime Environment 1.6.0_22-b04)