Java 中字节移位的奇怪行为

Mal*_*jam 5 java byte binary-operators bit-shift bitwise-operators

当我在 上使用位移位时byte,我注意到使用无符号右移 ( >>>)时得到了奇怪的结果。使用int,右移(signed:>>和 unsigned: >>>)都按预期运行:

    int min1 = Integer.MIN_VALUE>>31; //min1 = -1
    int min2 = Integer.MIN_VALUE>>>31; //min2 = 1
Run Code Online (Sandbox Code Playgroud)

但是当我对 做同样的byte事情时,无符号右移会发生奇怪的事情:

    byte b1 = Byte.MIN_VALUE; //b1 = -128
    b1 >>= 7; //b1 = -1

    byte b2 = Byte.MIN_VALUE; //b2 = -128
    b2 >>>= 7; //b2 = -1; NOT 1!
    b2 >>>= 8; //b2 = -1; NOT 0!
Run Code Online (Sandbox Code Playgroud)

我认为可能是编译器在内部将 转换byteint,但似乎不足以解释这种行为。

为什么在 Java 中对字节进行位移位的行为是这样的?

Ale*_*you 6

这种情况正是因为byte晋升int前执行按位运算。int -128表示为:

11111111 11111111 11111111 10000000
Run Code Online (Sandbox Code Playgroud)

因此,右移 7 位或 8 位仍然使第 7 位为 1,因此结果缩小为负值byte

相比:

System.out.println((byte) (b >>> 7));           // -1
System.out.println((byte) ((b & 0xFF) >>> 7));  //  1
Run Code Online (Sandbox Code Playgroud)

通过b & 0xFF,所有最高位在移位前被清除,因此结果如预期产生。