不幸的是,我认为您期望 Java char 与 Unicode 代码点相同。它们不是一回事。
正如其他答案已经表达的那样,Java char 只能支持可以用 16 位表示的代码点,而 Unicode 需要 21 位才能支持所有代码点。
换句话说,Java char 本身仅支持基本多语言平面字符(代码点 0xFFFF)。在 Java 中,如果您想表示位于其中一个扩展平面中的 Unicode 代码点(代码点 > 0xFFFF),那么您需要代理字符或一对字符来执行此操作。这就是UTF-16 的工作原理。而且,在内部,这也是 Java 字符串的工作方式。只是为了好玩,运行以下 sn -p 来查看单个 Unicode 代码点实际上是如何用 2 个字符表示的,如果代码点 >0xFFFF:
// Printing string length for a string with
// a single unicode code point: 0x22BED.
System.out.println("?".length()); // prints 2, because it uses a surrogate pair.
如果您想安全地将表示 Unicode 代码点的 int 值转换为 char(或者更准确地说是 chars),然后将其转换回 int 代码点,你将不得不使用这样的代码:
public static void main(String[] args) {
int hex = 0x10FFFF;
System.out.println(Character.isSupplementaryCodePoint(hex)); // prints true because hex > 0xFFFF
char[] surrogateChars = Character.toChars(hex);
int codePointConvertedBack = Character.codePointAt(surrogateChars, 0);
System.out.println(codePointConvertedBack); // prints 1114111
}
或者,您可以使用String,而不是操作char 数组,如下所示:
public static void main(String[] args) {
int hex = 0x10FFFF;
System.out.println(Character.isSupplementaryCodePoint(hex)); // prints true because hex > 0xFFFF
String s = new String(new int[] {hex}, 0, 1);
int codePointConvertedBack = s.codePointAt(0);
System.out.println(codePointConvertedBack); // prints 1114111
}
进一步阅读:Java Character Class