这段代码是java1.8种util.ArrayList中关于数组扩容的一段代码, 上面有一行//overflow-conscious code. 说明下面的代码是对溢出进行考虑的代码 ,但是我花了好多时间在上面仍没有想清楚他是如何避免溢出的, 以及如何在newCapacity溢出的情况下工作的, 望指点迷津
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
配列がオーバーフローしそうな場合は、配列の 1/2 を加算し、配列の最大の定数と比較し、配列の最大サイズを超える場合は、
Integer.MAX_VALUE
の新しい配列を適用します。をクリックして、古い Copy the array を追加します。理解するのが最も難しいのは
>>1
ですが、これは実際には 2 で割ることと同じです。簡単な例を書くと、デバッグ後にわかります
リーリー この文の実行後にint newCapacity = oldCapacity + (oldCapacity >> 1);
が int の最大値を超える場合、newCapacity
は負の数になります。これには、デジタル バイナリの加算と減算の原理を理解する必要があります。以下の4文は
リーリーnewCapacity
オーバーフローが負の数になった場合の対処ですあなたは、同じ配列リストを複数のスレッドで操作することについて話していると思います。このとき、長さのオーバーフローの問題が発生しました。正しい方法は、配列リストがスレッドセーフではないことです。同時。CopyOnWriteArrayList