你指出的行为确实是违反直觉的。 但是,此行为是由javadoc为int positive = value & Integer.MAX_VALUE指定的行为:
如果参数不是负数,则返回参数。 如果参数为负数,则返回参数的否定。
也就是说,int positive = value & Integer.MAX_VALUE的行为应该类似于以下Java代码:
public static int abs(int x){
if (x >= 0) {
return x;
}
return -x;
}
也就是说,在否定的情况下,int positive = value & Integer.MAX_VALUE。
根据JLS部分15.15.4,int positive = value & Integer.MAX_VALUE等于Integer.MAX_VALUE,其中0是按位补码运算符。
要检查这听起来是否正确,让我们以-1为例。
整数值int positive = value & Integer.MAX_VALUE可以在Java中以十六进制表示为Integer.MAX_VALUE(使用0或任何其他方法检查)。 以Integer.MIN_VALUE为例给出:
-(-1) = (~(0xFFFFFFFF)) + 1 = 0x00000000 + 1 = 0x00000001 = 1
所以,它的工作原理。
让我们现在尝试使用int positive = value & Integer.MAX_VALUE。 知道最低整数可以由int positive = value & Integer.MAX_VALUE表示,即第一位设置为1而其余31位设置为0,我们有:
-(Integer.MIN_VALUE) = (~(0x80000000)) + 1 = 0x7FFFFFFF + 1
= 0x80000000 = Integer.MIN_VALUE
这就是为什么int positive = value & Integer.MAX_VALUE返回Integer.MAX_VALUE.另请注意,0是Integer.MIN_VALUE。
也就是说,我们怎样才能避免将来由于这种反直觉的回报价值而产生的问题呢?
正如@Bombe指出的那样,我们可以将我们的int positive = value & Integer.MAX_VALUEs投入到Integer.MAX_VALUE之前。 但是,我们必须要么
把它们扔回int positive = value & Integer.MAX_VALUEs,这是行不通的,因为Integer.MAX_VALUE。
或继续int positive = value & Integer.MAX_VALUEs以某种方式希望我们永远不会调用Integer.MAX_VALUE,其值等于0,因为我们也有Integer.MIN_VALUE。
我们到处都可以使用int positive = value & Integer.MAX_VALUEs,因为int positive = value & Integer.MAX_VALUE确实总是返回正值。 这是一个很好的选择,比操作原始整数类型要慢一点。
我们可以为int positive = value & Integer.MAX_VALUE编写自己的包装器,如下所示:
/**
* Fail-fast wrapper for {@link Math#abs(int)}
* @param x
* @return the absolute value of x
* @throws ArithmeticException when a negative value would have been returned by {@link Math#abs(int)}
*/
public static int abs(int x) throws ArithmeticException {
if (x == Integer.MIN_VALUE) {
// fail instead of returning Integer.MAX_VALUE
// to prevent the occurrence of incorrect results in later computations
throw new ArithmeticException("Math.abs(Integer.MIN_VALUE)");
}
return Math.abs(x);
}
使用整数按位AND清除高位,确保结果为非负数:int positive = value & Integer.MAX_VALUE(基本上从Integer.MAX_VALUE溢出到0而不是Integer.MIN_VALUE)
最后一点,这个问题似乎已经有一段时间了。 有关相应的findbugs规则,请参阅此条目。