Java:char范围超过2个字节的整数的unicode表示

时间:2014-09-24 18:27:09

标签: java unicode

当我运行以下语句时,

    System.out.println("Character is "+(char)65534); //equivalent to 0xfffe
    System.out.println("Character is "+(char)65535); //equivalent to 0xffff
    System.out.println("Character is "+(char)65536); //equivalent to 0x10000
    System.out.println("Character is "+(char)65537); //equivalent to 0x10001

我得到输出为

Character is _              where _ is \ufffe
Character is _              where _ is \uffff
Character is 
Character is 

在SO上读到关于为什么输出这个输出的答案,这是因为char类型是2个字节(这是Java的UTF-16格式所发生的),所以第3和第4行的输出由于超出2个字节的限制,它们是空的。所以,我查看了String类来获取超过2个字节的整数的unicode表示。它的一个函数codePointAt返回字符串中字符的整数等价物。所以,我寻找它的反向/反函数,但似乎没有这样的函数。

任何人都可以请我指向Java中的标准函数来执行此类功能。如果它不存在,那么请指导我如何获得代码点的unicode表示(Java使用高和低代理表示3字节及以上,所以有两个代码点)从头开始。

编辑:

问题主要涉及在值为大于0xffff的代码点的print语句中显示unicode描述。

3 个答案:

答案 0 :(得分:0)

Character类提供以下方法

Character.highSurrogate(codePoint);
Character.lowSurrogate(codePoint);

用于检索代理项,给定代码点。

有了这些内容后,您可以将其写入ByteBuffer并获取相应的byte[]并使用它创建一个采用UTF-16编码的新String

//  byte[] bytes = new byte[] { (byte) 0xD8, 0x34, (byte) 0xDD, 0x1E };
String text = ""; // new String(bytes, StandardCharsets.UTF_16);
int codePoint = text.codePointAt(0);

ByteBuffer buf = ByteBuffer.allocate(4);
buf.putChar(Character.highSurrogate(codePoint));
buf.putChar(Character.lowSurrogate(codePoint));
byte[] data = buf.array();

// recreated
String rep = new String(data, StandardCharsets.UTF_16); 

答案 1 :(得分:0)

方法Character.toChars(int)将为您提供与该代码点对应的UTF-16系列代码单元。

所以,举个例子:

System.out.println("Character is " + new String(Character.toChars(65536))); //equivalent to U+10000
假设您有该字体,

将打印U + 10000('LINEAR B SYLLABLE B008 A')。

答案 2 :(得分:0)

Java被设计为以Unicode格式保存文本,因此可以组合所有语言的所有脚本(例如西里尔文,阿拉伯文,希腊文)。

Unicode符号称为代码点,是需要3个字节的数字。 U + 10000将是您提到的代码点。它是线性B音节B008 A。

代码点存储在Java中的int中。 String持有char数组,其中char是2字节UTF-16BE编码值。当Unicode进入3字节范围时,有时需要2个字符来表示一个代码点。 UTF-16编码可确保在字节中不会错误地找到诸如/之类的ASCII字符。

此外,java将字符串文字,类和方法名称以UTF-8格式存储在.class文件中。 UTF-8是一种多字节编码。

  • UTF-8具有7位ASCII码点作为子集,字节序列(byte)0x63实际上是码点U + 0063 aka'c'。
  • UTF-16在Unicode中有很大一部分作为子集:char \u10000的确是代码点U + 10000。

因此,使用char值始终是部分解决方案。最好使用代码点。

答案:

System.out使用默认的平台编码,并且将无法表示所有Unicode。另外,控制台字体必须能够描述代码点。当无法进行转换时,大多数会显示?<?>占位符。

解决方案是使用UTF-8写入文件。然后以UTF-8格式打开文件,例如使用记事本++,然后安装巨大的Unicode字体。