我发现了一些关于位运算符和位移的奇怪行为。我试图通过使用位掩码来加速一个小检查,然后我遇到了这个:
public class Weirdness {
private final static int constant = 3;
private static int notConstant = 3;
public void stuff() {
byte a = 0b1 << 3;
byte b = 0b1 << (int) 3;
byte c = 0b1 << constant;
byte d = 0b1 << notConstant; //error
byte e = 0b1 << getAnInt(); //error
byte f = 0b1 << getAFinalInt(); //error
int i = 3;
byte g = 0b1 << i; //error
final int j = 3;
byte h = 0b1 << j;
}
public static int getAnInt() {
return 3;
}
public static final int getAFinalInt() {
return 3;
}
}
a
, b
, c
和h
不会导致编译错误;但d
, e
, f
和g
会。编译器要求显式地将它们强制转换为byte
或将最后一个变量声明为int
。我也注意到了使用位运算符&
和|
时有类似的行为。
有人能解释一下这里发生了什么吗?
编译器是如何实现对a
, b
, c
和h
的工作的?
编辑:或者说这并不完全是重复的问题
我认为这个问题与为什么我不能将两个字节相加并得到一个整数,而我可以将两个final字节相加得到一个字节?不同,因为引起有趣行为的原因是编译器如何优化位移操作。
由于我寻求的是一个理论上的答案(因为我已经明白我可以通过强制转换使我的代码编译),解释位移和其他位运算如何确定它们的返回值,因此我认为这个问题可以补充Java - bit shifting with integers and bytes并为StackOverflow带来更多有趣的信息。