先给出一个问题
public static void main(String[] args) {
int x = -2147483648;
int abs = Math.abs(x);
// false
System.out.println(abs > 0);
//-2147483648
System.out.println(abs);
}
看到这个种情况,第一反应就是去看看Math.abs的源码,及如下
public static int abs(int a) {
return (a < 0) ? -a : a;
}
看到这里,如果了解溢出问题就可以找到大概原因了,不知道也没关系,看看Integer.MAX_VALUE, Integer.MIN_VALUE的值就会明白了
// MIN_VALUE = 0x80000000 = -2147483648
@Native public static final int MIN_VALUE = 0x80000000;
// MAX_VALUE = 0x7fffffff =2147483647
@Native public static final int MAX_VALUE = 0x7fffffff;
所以 -1 * Integer.MIN_VALUE 会导致溢出 ,相当于 Integer.MAX_VAVLUE + 1
public static void main(String[] args) {
int x = -2147483648;
// true
System.out.println(x == Integer.MIN_VALUE);
//-2147483648
System.out.println(-1 * Integer.MIN_VALUE);
// true
System.out.println(-1 * Integer.MIN_VALUE == Integer.MIN_VALUE);
// -2147483648
System.out.println(Integer.MAX_VALUE + 1);
// true
System.out.println(Integer.MAX_VALUE + 1 == Integer.MIN_VALUE);
}
解决方法
使用long类型的 重载方法 Math.abs(long a)
public static long abs(long a) {
return (a < 0) ? -a : a;
}
public static int abs(int a) {
return (a < 0) ? -a : a;
}
public static float abs(float a) {
return (a <= 0.0F) ? 0.0F - a : a;
}
public static double abs(double a) {
return (a <= 0.0D) ? 0.0D - a : a;
}
个人疑惑
jdk 设计的时候为什么,不经行判断呢,避免溢出问题(这个bug 很难发现),比如说可以这样设计:
// 用int类型重载方法举例
public static int abs(int a) {
if (a==Integer.MIN_VALUE) {
throw new InvalidParameterException();
}
return (a < 0) ? -a : a;
}



