如果我将一个字符转换为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 行写什么?
Java 中的字符是一个 Unicode 代码单元,它被视为无符号数。所以如果你执行
c = (char)b
你得到的值是 2^16 - 56 或 65536 - 56。或者更准确地说,该字节首先被转换为一个带符号整数,该值在扩展转换中
0xFFFFFFC8
使用符号扩展。0xFFC8
当转换为 a 时char
,这反过来又会缩小到 a ,这转化为正数65480
。从语言规范:
5.1.4. 扩大和缩小原始转换
要获得正确的点
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
.