呵呵,好奇。我认为这是一种“有意的漏洞”,可以这么说。
根本原因在于Integer类的编写方式。基本上,parseInt被“优化”用于正数。当它解析字符串时,它会累加地构建结果,但是取反。然后它翻转最终结果的符号。
例如:
66 = 0x42
像这样解析:
4*(-1) = -4
-4 * 16 = -64 (hex 4 parsed)
-64 - 2 = -66 (hex 2 parsed)
return -66 * (-1) = 66
现在,让我们来看看你的例子
FFFF8000
16*(-1) = -16 (first F parsed)
-16*16 = -256
-256 - 16 = -272 (second F parsed)
-272 * 16 = -4352
-4352 - 16 = -4368 (third F parsed)
-4352 * 16 = -69888
-69888 - 16 = -69904 (forth F parsed)
-69904 * 16 = -1118464
-1118464 - 8 = -1118472 (8 parsed)
-1118464 * 16 = -17895552
-17895552 - 0 = -17895552 (first 0 parsed)
Here it blows up since -17895552 < -Integer.MAX_VALUE / 16 (-134217728).
Attempting to execute the next logical step in the chain (-17895552 * 16)
would cause an integer overflow error.
编辑(补充):为了使parseInt()在-Integer.MAX_VALUE <= n <= Integer.MAX_VALUE的范围内“一致”工作,他们必须实现逻辑来在累积结果达到-Integer.MAX_VALUE时“旋转”,从整数范围的最大端重新开始,并从那里向下继续。为什么他们没有这样做,我们不得不问Josh Bloch或者是第一次实现它的人。这可能只是一种优化。
然而,
Hex=Integer.toHexString(Integer.MAX_VALUE);
System.out.println(Hex);
System.out.println(Integer.parseInt(Hex.toUpperCase(), 16));
这个很好地工作,正是因为这个原因。在 Integer 的源代码中,你可以找到这个注释。
// Accumulating negatively avoids surprises near MAX_VALUE
int firstAttempt = 5;
- Simulant