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)
ますか?