a < b
并且a - b < 0
可能意味着两个不同的东西。考虑以下代码:
int a = Integer.MAX_VALUE;
int b = Integer.MIN_VALUE;
if (a < b) {
System.out.println("a < b");
}
if (a - b < 0) {
System.out.println("a - b < 0");
}
运行时,将仅打印a - b < 0
。发生的事情a < b
显然是错误的,但是a - b
溢出并变为-1
,这是负面的。
话虽如此,请考虑一下数组的长度确实接近Integer.MAX_VALUE
。中的代码ArrayList
如下所示:
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
oldCapacity
确实接近,Integer.MAX_VALUE
所以newCapacity
(是oldCapacity + 0.5 * oldCapacity
)可能溢出并变成Integer.MIN_VALUE
(即负数)。然后,将minCapacity
下溢相减回正数。
此检查确保if
不会执行。如果代码编写为if (newCapacity < minCapacity)
,则true
在这种情况下(因为它newCapacity
为负),所以无论否newCapacity
都将强制minCapacity
执行oldCapacity
。
此溢出情况由下一个if处理。当newCapacity
已经溢出,这将是true
:MAX_ARRAY_SIZE
被定义为Integer.MAX_VALUE - 8
和Integer.MIN_VALUE - (Integer.MAX_VALUE - 8) > 0
的true
。将newCapacity
因此被正确地处理:hugeCapacity
方法返回MAX_ARRAY_SIZE
或Integer.MAX_VALUE
。
注意:这就是// overflow-conscious code
此方法中的注释。
if (newCapacity - minCapacity < 0)
什么比if (newCapacity < minCapacity)
防止溢出更好的了?