我不理解以下代码的输出:
public static void main(String[] args) {
int i1, i2, i3, i4;
byte b;
i1 = 128;
b = (byte) i1;
i2 = (int) b;
i3 = 0 | b;
i4 = 1 << 7;
System.out.format("i1: %d b: %d i2: %d i3: %d i4: %d\n", i1, b, i2, i3, i4);
}
输出:
i1: 128 b: -128 i2: -128 i3: -128 i4: 128
因为byte
是一个8位two's-complement有符号整数,所以最高有效位为1的二进制表示被解释为负值,这就是b
成为{{}的原因。 1}},我完全没问题。我也明白,在投射时保持解释一致可能是个好主意,就像使用-128
一样。但是,i2
和i3
不应该具有相同的位模式,因此会映射到相同的i4
值吗?
答案 0 :(得分:5)
在这一行:
i3 = 0 | b;
由于int
运算符,“b”变量会自动提升为带有符号扩展名的|
类型,因此变为(int)-128
,即0xffffff80
。
当“或”ed为零时,它仍然是相同的值,即-128
答案 1 :(得分:4)
不,i4
不是字节值,而是int
。这意味着它的符号位是第31位,而不是第7位。
更新:i3
也是int
,但是通过扩展byte
进行初始化,因此它会保留byte
的符号}值。
答案 2 :(得分:4)
签名扩展使得i2
和i3
为负。
在表达式(0 | b)
中,b
被提升为int,并且此促销中会出现符号扩展名。
分配给i4
的表达式中没有发生这种情况。常量1
和7
已经是整数,因此不会涉及符号扩展。
答案 3 :(得分:2)
i2 = (int) b;
i3 = 0 | b;
i3语句相当于:
i3 = 0 | ((int) b) = 0 | i2
所以很自然它会与i2
答案 4 :(得分:1)
在
i3 = 0 | b;
我猜0 | b part被评估为一个字节,然后将结果转换为int,而在
中i4 = 1 << 7;
1&lt;&lt; 7部分已经是一个int。
上述猜测已经在评论中指出是错误的!
正确的版本是:在顶部表达式中,在OR操作之前,b已经被转换为带符号扩展名的int。
答案 5 :(得分:1)
这很简单。 i3 = 0 | b;
评估为byte
,然后转换为int
。而i4 = 1 << 7;
会将值评估为int
,并将其分配给int
。因此,在第一种情况下,我们会从10000000b
向int
投放byte
,这会给我们-128
。在第二个中,我们只是将此值分配给int
而不进行强制转换,这样我们就可以128
。
答案 6 :(得分:1)