a < b
et a - b < 0
peut signifier deux choses différentes. Considérons le code suivant:
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");
}
Lorsqu'il est exécuté, ce sera seulement imprimer a - b < 0
. Ce qui se passe c'est qu' a < b
est clairement faux, mais a - b
déborde et devient -1
, ce qui est négatif.
Maintenant, après avoir dit que, considèrent que le tableau a une longueur qui est vraiment proche de l' Integer.MAX_VALUE
. Le code en ArrayList
va comme ceci:
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
est vraiment proche de l' Integer.MAX_VALUE
donc newCapacity
(ce qui est oldCapacity + 0.5 * oldCapacity
) risque de débordement et de devenir Integer.MIN_VALUE
(c'est à dire de négatif). Puis, en soustrayant minCapacity
underflows de retour dans un nombre positif.
Ce contrôle permet de s'assurer que l' if
n'est pas exécutée. Si le code ont été écrites en if (newCapacity < minCapacity)
, il serait true
dans ce cas (depuis newCapacity
est négatif) de sorte que le newCapacity
serait forcé d' minCapacity
quel que soit le oldCapacity
.
Ce cas de dépassement de capacité est gérée par l'autre si. Lors de l' newCapacity
a débordé, ce sera true
: MAX_ARRAY_SIZE
est défini comme Integer.MAX_VALUE - 8
et Integer.MIN_VALUE - (Integer.MAX_VALUE - 8) > 0
est true
. L' newCapacity
est donc à juste titre traités: hugeCapacity
méthode renvoie MAX_ARRAY_SIZE
ou Integer.MAX_VALUE
.
NB: c'est ce que l' // overflow-conscious code
commentaire dans cette méthode, c'est dire.