Java自动型促销

我引用Herbert Schildt的话:JAVA,The Complete Reference 8th Edition。

第4章:运营商

当您移动字节和短值时,Java的自动类型促销会产生意外结果。 如您所知,在计算表达式时,字节和短值将提升为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的新手。

i2的值是(二进制) 1110 1100或(十进制) -20

Integer.toBinaryString(int)的参数类型是int ,因此i2被提升为int 。 这涉及符号扩展 ,这意味着“符号位”(负数的前导1或正数或前导的0 )被复制到所有更高的位,产生(二进制) 1111 1111 1111 1111 1111 1111 1110 1100或(十进制) -20

当你查看二进制表示时,它可能看起来很奇怪,但是当你查看十进制表示时它是有意义的。 符号扩展的目的是保留实际的数值。