JDK1.8 ArrayList源码中为何用A-B>0判断大小而非A>B?
核心原因是处理整数溢出导致的异常类型错误,具体来说:
Java的int是32位有符号整数,最大值是Integer.MAX_VALUE(231-1),最小值是`Integer.MIN_VALUE`(-231)。当需要的最小容量minCapacity超过最大值时,会发生溢出,变成负数(比如Integer.MAX_VALUE + 1会溢出成Integer.MIN_VALUE)。
如果直接用
minCapacity > elementData.length判断:
当minCapacity溢出为负数时,负数肯定小于正数的数组长度elementData.length,条件不成立,不会触发扩容grow()。后续尝试往数组里添加元素时,会抛出ArrayIndexOutOfBoundsException(数组越界),但这时候的问题本质是需要的容量超出了int的范围,应该抛出OutOfMemoryError才对。用
minCapacity - elementData.length > 0判断:
当minCapacity是Integer.MIN_VALUE(溢出后的负数),减去正数的elementData.length时,会再次溢出:比如Integer.MIN_VALUE - 1会溢出成Integer.MAX_VALUE(正数),这时候条件>0成立,会进入grow()方法。在grow()里的hugeCapacity()方法会检测到minCapacity < 0,抛出正确的OutOfMemoryError,准确反映问题本质。
另外,这种写法也和grow()方法里的判断逻辑(比如newCapacity - minCapacity < 0)保持了一致,统一了代码风格。
内容的提问来源于stack exchange,提问作者shy Ren

