Java中的字节和字符转换

时间:2013-07-28 20:38:37

标签: java encoding unicode utf-16

如果我将一个角色转换为byte然后又回到char,那个角色会神秘地消失并成为别的东西。这怎么可能?

这是代码:

char a = 'È';       // line 1       
byte b = (byte)a;   // line 2       
char c = (char)b;   // line 3
System.out.println((char)c + " " + (int)c);

直到第2行一切都很好:

  • 在第1行,我可以在控制台中打印“a”,它会显示“È”。

  • 在第2行中,我可以在控制台中打印“b”,它会显示-56,即200,因为字节已签名。 200是“È”。所以它仍然很好。

但第3行出了什么问题? “c”变为其他内容,程序打印? 65480。这是完全不同的东西。

我应该在第3行写什么才能得到正确的结果?

2 个答案:

答案 0 :(得分:51)

Java中的字符是Unicode代码单元,被视为无符号数字。因此,如果您执行c = (char)b,则得到的值是2 ^ 16 - 56或65536 - 56。

或者更确切地说,在扩展转换中,首先使用符号扩展将字节转换为值为0xFFFFFFC8的有符号整数。然后,当转换为0xFFC8时,这会缩小为char,转换为正数65480

来自语言规范:

5.1.4. Widening and Narrowing Primitive Conversion

  

首先,通过扩展原语转换(第5.1.2节)将字节转换为int,   然后通过缩小基元转换将结果int转换为char   (§5.1.3)。


要获得正确的点,请使用char c = (char) (b & 0xFF)首先使用掩码将b的字节值转换为正整数200,将转换后的前24位置零:{{ 1}}变为0xFFFFFFC8或正数0x000000C8的小数。


以上是对200byteint基元类型转换期间发生的情况的直接解释。

如果要对字节进行编码/解码,请使用charCharsetCharsetEncoder或其中一种便捷方法,例如CharsetDecoder或{{1} }。您可以从new String(byte[] bytes, Charset charset)获取字符集(例如UTF-8或Windows-1252)。

答案 1 :(得分:0)

new String(byteArray, Charset.defaultCharset())

这会将字节数组转换为Java中的默认字符集。可能会抛出异常,具体取决于您为byteArray提供的内容。