class D {
public static void main(String args[]) {
Integer b2=128;
Integer b3=128;
System.out.println(b2==b3);
}
}
Sortie:
false
class D {
public static void main(String args[]) {
Integer b2=127;
Integer b3=127;
System.out.println(b2==b3);
}
}
Sortie:
true
Remarque: les nombres compris entre -128 et 127 sont vrais.
Lorsque vous compilez un littéral numérique dans Java et l'affectez à un entier (majuscule I
), le compilateur émet:
Integer b2 =Integer.valueOf(127)
Cette ligne de code est également générée lorsque vous utilisez la mise en boîte automatique.
valueOf
est implémenté de telle sorte que certains nombres sont "regroupés" et renvoie la même instance pour les valeurs inférieures à 128.
À partir du Java 1.6, ligne 621:
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
La valeur de high
peut être configurée sur une autre valeur, avec la propriété système.
-Djava.lang.Integer.IntegerCache.high = 999
Si vous exécutez votre programme avec cette propriété système, il affichera true!
La conclusion évidente: ne jamais se fier à deux références identiques, toujours les comparer avec la méthode .equals()
.
Ainsi, b2.equals(b3)
affichera vrai pour toutes les valeurs logiquement égales de b2, b3.
Notez que Integer
cache n'est pas là pour des raisons de performances, mais plutôt pour se conformer à JLS, section 5.1.7 ; l'identité de l'objet doit être donnée pour les valeurs -128 à 127 inclus.
Integer # valueOf (int) documente également ce comportement:
cette méthode est susceptible de produire des performances d'espace et de temps nettement meilleures en mettant en cache les valeurs fréquemment demandées. Cette méthode mettra toujours en cache les valeurs comprises entre -128 et 127 inclus et peut mettre en cache d'autres valeurs en dehors de cette plage.
Autoboxing met en cache -128 à 127. Ceci est spécifié dans le JLS ( 5.1.7 ).
Si la valeur p encadrée est vraie, fausse, un octet, un caractère compris entre\u0000 et\u007f, ou un nombre entier ou court entre -128 et 127, alors que r1 et r2 soient les résultats de deux conversions de boxe quelconques de p. Il est toujours vrai que r1 == r2.
Une règle simple à retenir lorsque vous traitez des objets est - utilisez .equals
si vous voulez vérifier si les deux objets sont "égaux", utilisez ==
lorsque vous voulez voir s'ils pointent vers la même instance.
L'utilisation de types de données primitifs, les entiers, produirait dans les deux cas la sortie attendue.
Cependant, puisque vous utilisez des objets Integer, l'opérateur == a une signification différente.
Dans le contexte des objets, == vérifie si les variables font référence à la même référence d'objet.
Pour comparer la valeur des objets, vous devez utiliser la méthode equals () Par exemple.
b2.equals(b1)
qui indiquera si b2 est inférieur à b1, supérieur ou égal à (consultez l'API pour plus de détails)
Il s'agit d'optimisation de la mémoire dans Java.
Pour économiser de la mémoire, Java 'réutilise' tous les objets wrapper dont les valeurs se situent dans les plages suivantes:
Toutes les valeurs booléennes (vrai et faux)
Toutes les valeurs d'octets
Toutes les valeurs de caractères de\u0000 à\u007f (c'est-à-dire de 0 à 127 en décimal)
Toutes les valeurs courtes et entières de -128 à 127.
Jetez un œil à Integer.Java, si la valeur est comprise entre -128 et 127, il utilisera le pool mis en cache, donc (Integer) 1 == (Integer) 1
tandis que (Integer) 222 != (Integer) 222
/**
* Returns an {@code Integer} instance representing the specified
* {@code int} value. If a new {@code Integer} instance is not
* required, this method should generally be used in preference to
* the constructor {@link #Integer(int)}, as this method is likely
* to yield significantly better space and time performance by
* caching frequently requested values.
*
* This method will always cache values in the range -128 to 127,
* inclusive, and may cache other values outside of this range.
*
* @param i an {@code int} value.
* @return an {@code Integer} instance representing {@code i}.
* @since 1.5
*/
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}