>> [Java] 的原始促销

primitive promotion for >> [Java]

我在下一个代码片段中遇到了原始提升的误解。

byte a = 2;
int b = a >> 4L;

我会期待什么?

long b = (int)a >> 4L;
long b = a >> 4L;
int b = a >> 4L;

int >> long 将提升为更大的数据类型 (long),并且不会使用结果 int 类型进行编译。

我收到了什么?

编译正常。 为什么?

JLS:

The type of the shift expression is the promoted type of the left-hand operand.

移位运算符的右手操作数对表达式的类型没有任何影响。与像 + 这样的运算符不同,右边更大的类型并不意味着结果可能更大或更小。

JLS 不会在这里"promote to the larger datatype",因为它不对移位运算符执行二进制数字提升。 JLS, Section 15.19.

涵盖了这一点

Unary numeric promotion (§5.6.1) is performed on each operand separately. (Binary numeric promotion (§5.6.2) is not performed on the operands.)

一元数字提升将字节 a 提升为 int。字面量4L没变,反正只要是整型就可以了

It is a compile-time error if the type of each of the operands of a shift operator, after unary numeric promotion, is not a primitive integral type.

然后对于移位,只使用最低5位有效位来移位int

If the promoted type of the left-hand operand is int, then only the five lowest-order bits of the right-hand operand are used as the shift distance. It is as if the right-hand operand were subjected to a bitwise logical AND operator & (§15.22.1) with the mask value 0x1f (0b11111). The shift distance actually used is therefore always in the range 0 to 31, inclusive.

运算符的结果是 int,而不是 long,因此可以将其分配给 int 而不会出现编译器错误。

The type of the shift expression is the promoted type of the left-hand operand.