Java中的字节和字符转换
如果我将一个字符转换为byte
然后再转换为字符,则该字符会神秘地消失并成为其他内容。 这怎么可能?
这是代码:
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
? 65480
这是完全不同的东西。
我应该在第3行写什么才能得到正确的结果?
Java中的字符是Unicode代码单元,被视为无符号数字。 因此,如果你执行c = (char)b
,你得到的值是2 ^ 16 – 56或65536 – 56。
或者更准确地说,首先在扩展转换中使用符号扩展将字节转换为值为0xFFFFFFC8
有符号整数。 然后在转换为char
时将其缩小到0xFFC8
,转换为正数65480
。
从语言规范:
5.1.4。 扩大和缩小原始转换
首先,通过扩展原语转换(第5.1.2节)将字节转换为int,然后通过缩小基元转换(第5.1.3节)将结果int转换为char。
要获得正确的点,请使用char c = (char) (b & 0xFF)
,它首先使用掩码将b
的字节值转换为正整数200
,将转换后的前24位置零: 0xFFFFFFC8
变为0x000000C8
或正数小数为200
。
以上是对byte
, int
和char
原语类型之间转换过程中发生的事情的直接解释。
如果要对字节进行编码/解码,请使用Charset
, CharsetEncoder
, CharsetDecoder
或其中一种方便方法,如new String(byte[] bytes, Charset charset)
或String#toBytes(Charset charset)
。 您可以从StandardCharsets
获取字符集(例如UTF-8或Windows-1252)。