在Java中将char作为一个字节处理,结果不同

时间:2011-02-14 09:00:26

标签: java unicode binary char byte

为什么以下两个结果不同?

bsh % System.out.println((byte)'\u0080');
-128

bsh % System.out.println("\u0080".getBytes()[0]);
63

感谢您的回答。

5 个答案:

答案 0 :(得分:5)

(byte)'\u0080'只取代码点的数值,该值不适合byte,因此受narrowing primitive conversion的影响,它会丢弃不适合的值字节和,因为设置了最高位,产生负数。

"\u0080".getBytes()[0]根据您的平台默认编码将字符转换为字节(有一个允许您指定编码的重载getBytes()方法)。看起来您的平台默认编码不能代表代码点U + 0080,并将其替换为“?” (代码点U + 003F,十进制值63)。

答案 1 :(得分:3)

Unicode字符U+0080 <control>无法在您的系统默认编码中表示,因此当{{1}将字符串编码为默认编码时,将由?(ASCII代码0x3F = 63)替换}。

答案 2 :(得分:2)

这里的字节数组有2个元素 - 这是因为unicode字符的表示不适合1个字节。

在我的机器上,数组包含[-62, -128]。那是因为我的默认编码是UTF-8。如果不指定编码,请勿使用getBytes()

答案 3 :(得分:1)

当你有一个字符编码不支持的字符时,它会变成'?'这是ASCII中的63。

System.out.println(Arrays.toString("\u0080".getBytes("UTF-8")));

打印

[-62, -128]

答案 4 :(得分:0)

实际上,如果您希望通过toString()调用获得相同的结果,请将UTF-16_LE指定为字符集编码:

bsh %  System.out.println("\u0080".getBytes("UTF-16LE")[0]); 
-128

Java字符串在内部编码为UTF-16,因为我们想要低级字节,如铸造字符 - &gt;字节,我们在这里使用小端。如果我们更改数组索引,Big endian也可以工作:

bsh %  System.out.println("\u0080".getBytes("UTF-16BE")[1]);
-128