以下是代码:
int i = 200;
byte b = (byte) 200;
System.out.println(b);
System.out.println((short) (b));
System.out.println((b & 0xff));
System.out.println((short) (b & 0xff));
这是输出:
-56
-56
200
200
按位AND和0xff不应该改变b
中的任何内容,但显然它确实有效,为什么?
答案 0 :(得分:8)
它有效,因为200
超出了最大可能(签名)byte
,127
。由于此溢出,该值已分配-56
。值得-128
的最重要字节已设置。
11001000
前两个输出语句因此显示-56
,并且转换为short
将执行符号扩展以保留负值。
执行& 0xff
时,会发生两件事。首先,该值会提升为int
,并带有符号扩展名。
11111111 11111111 11111111 11001000
然后,执行bit-and,仅保留最后8位。此处,第8位不再是-128
,而是128
,因此会恢复200
。
00000000 00000000 00000000 11001000
无论值是否转换为short
,都会发生这种情况; short
有16位,可以轻松代表200
。
00000000 11001000
答案 1 :(得分:1)
Java byte
是签名类型。这就是您在打印时看到负数的原因:200或0xC8
高于byte
可表示的最大正数,因此它被解释为负数byte
。< / p>
但是,0xff
常量是int
。在byte
和int
* 上执行算术和按位逻辑运算时,结果变为int
。这就是为什么您在第二组示例中看到200
打印的原因:(b & 0xff)
生成一个整数200
,在转换为200
之后仍为short
,因为200
符合short
而不会变为负面。
* 或其他byte
,就此而言; Java标准指定了根据操作数类型应用的转换列表。
答案 2 :(得分:0)
使用不同的整数类型是一个雷区。
例如,这里发生了什么?
byte b = (byte) 200;
它实际上相当于
int i = 200;
byte b = (byte)i;
并且缩小广播(byte)
只取int
值的最低8位。