我引用Herbert Schildt的话:JAVA,The Complete Reference 8th Edition。
第4章:运营商
当您移动字节和短值时,Java的自动类型提升会产生意外结果。如您所知,在计算表达式时,byte和short值将提升为int。此外,这种表达式的结果也是一个int。这意味着一个字节或一个短值左移的结果将是一个int,并且向左移位的位将不会丢失,直到它们移位到位31之后。
此外,当负字节或短值被提升为int时,它将被符号扩展。因此,高位将填充1。由于这些原因,对字节或短执行左移意味着必须丢弃int结果的高位字节。例如,如果左移一个字节值,则必须首先将该值提升为int然后再移位。这意味着如果您想要的是移位字节值的结果,则必须丢弃结果的前三个字节。最简单的方法是简单地将结果转换回一个字节。
byte a = 64, b;
int i;
i = a << 2;
b = (byte)(a<<2);
System.out.println("Binary Equivalent of b : "+Integer.toBinaryString(b)); // gives 0
byte i1 = -5,i2;
int s;
s = i1<<2;
i2 = (byte)(i1<<2);
System.out.println(Integer.toBinaryString(i2)); //gives 11111111111111111111111111101100
1111 1111 1111 1111 1111 1111 1110 1100是怎样的答案。我声明i2是字节的。因此它应该包含8位(一个字节)。为什么32位。或者根据前面提到的最后一段,我是否需要丢弃结果的前3个字节。詹姆斯·高斯林为什么这样设计它。这恰好是在负数(这里是-5)的情况下。不会发生在64.我想我不清楚赫伯特在第2段中说的是什么。请详细说明他希望解释的内容。我是Java的新人。
答案 0 :(得分:3)
i2
的值是(二进制)1110 1100
或(十进制)-20
。
Integer.toBinaryString(int)
的参数类型为int
,因此i2
会提升为int
。这涉及符号扩展,这意味着“符号位”(负数的前导1
或正数或零的前导0
被复制到所有更高的位,产生(二进制)1111 1111 1111 1111 1111 1111 1110 1100
或(十进制)-20
。
当您查看二进制表示时,它可能看起来很奇怪,但是当您查看十进制表示时它是有意义的。符号扩展的目的是保留实际的数值。