我在下一个代码片段中遇到了对原始提升的误解。
byte a = 2;
int b = a >> 4L;
我会期待什么?
long b = (int)a >> 4L;
long b = a >> 4L;
int b = a >> 4L;
int >> long
将提升为更大的数据类型 ( long
),并且不会使用结果int
类型进行编译。
我收到了什么?
它编译得很好。为什么?
我在下一个代码片段中遇到了对原始提升的误解。
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 不会在这里“提升到更大的数据类型”,因为它不为移位运算符执行二进制数字提升。JLS 第 15.19 节对此进行了介绍。
一元数字提升(第 5.6.1 节)分别对每个操作数执行。(二进制数字提升(第 5.6.2 节)不在操作数上执行。)
一元数字提升将字节a
提升为int
. 文字4L
没有改变,但无论如何它只需要是一个整数类型。
如果移位运算符的每个操作数的类型在一元数字提升后不是原始整数类型,则这是编译时错误。
然后对于移位,仅使用最低 5 个有效位来移位int
.
如果左侧操作数的提升类型是 int,则只有右侧操作数的五个最低位用作移位距离。就好像右手操作数受到按位逻辑与运算符 & (§15.22.1) 的影响,掩码值为 0x1f (0b11111)。因此,实际使用的移位距离始终在 0 到 31 的范围内,包括 0 到 31。
运算符的结果是 a int
,而不是 a long
,因此可以将其分配给 aint
而不会出现编译器错误。
移位表达式的类型是左侧操作数的提升类型。