Pourquoi est-128 == 128 faux mais 127 == 127 est vrai lorsque l'on compare les emballages entiers en Java?
-
19-09-2019 - |
Question
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 chiffres entre -128 et 127 sont vraies
.La solution
Lorsque vous compilez un littéral en Java et l'affecter à un nombre entier (I
de capital) émet le compilateur:
Integer b2 =Integer.valueOf(127)
Cette ligne de code est également généré lorsque vous utilisez autoboxing.
valueOf
est mis en œuvre de telle sorte que certains numéros sont « mis en commun », et il retourne la même instance pour des valeurs inférieures à 128.
Du code Java 1.6 source, à la 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é pour une autre valeur, avec la propriété du système.
-Djava.lang.Integer.IntegerCache.high = 999
Si vous exécutez votre programme avec cette propriété du système, il affichera vrai!
La conclusion évidente: ne jamais compter sur deux références identiques, les comparer toujours avec la méthode .equals()
b2.equals(b3)
imprimera vrai pour toutes les valeurs logiquement égales de b2, b3.
Notez que le cache de Integer
est pas là pour des raisons de performance, mais plutôt de se conformer à la balise JLS, section 5.1.7 ; l'identité d'objet doit être donné pour les valeurs -128 à 127 inclus.
Entier # valueOf (int) documente également ce comportement:
cette méthode est susceptible de donner beaucoup plus d'espace et le temps des performances en mettant en cache des valeurs fréquemment demandées. Cette méthode sera toujours mettre en cache les valeurs comprise entre -128 à 127, y compris, et peut mettre en cache d'autres valeurs en dehors de cette plage.
Autres conseils
Autoboxing met en cache -128 à 127. Ceci est spécifié dans la JLS ( 5.1.7 ).
Si la valeur p est vrai étant en boîte, faux, un octet, un caractère dans la gamme \ u0000 à \ u007f, ou un int ou court entre -128 et 127, alors laissez-r1 et r2 soient les résultats des deux conversions de boxe de p. Il est toujours le cas que r1 == r2.
Une règle simple à retenir lors de traiter des objets est - l'utilisation .equals
si vous voulez vérifier si les deux objets sont « égaux », l'utilisation ==
lorsque vous voulez voir s'ils pointent à la même instance
Utilisation des types de données primitifs, ints, produirait vrai dans les deux cas, le résultat attendu.
Cependant, puisque vous utilisez des objets Integer l'opérateur == a un sens différent.
Dans le contexte des objets, == vérifie pour voir si les variables se réfèrent à 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 indique si b2 est inférieure à b1, supérieure ou égale à (vérifier l'API pour plus de détails)
Il est l'optimisation de la mémoire liée à Java.
Pour enregistrer sur la mémoire, tous les objets wrapper 'réutilise de Java dont les valeurs tomber les plages suivantes:
Toutes les valeurs booléennes (vrai et faux)
Toutes les valeurs d'octets
Toutes les valeurs de caractères \ u0000 to \ u007f (à savoir 0 à 127 en décimal)
Toutes les valeurs à court et entier de -128 à 127.
Jetez un oeil à la Integer.java, si la valeur est comprise entre -128 et 127, il utilisera la piscine en cache, de sorte (Integer) 1 == (Integer) 1
tout (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);
}
J'ai écrit ce qui suit comme ce problème est non seulement spécifique à Integer. Ma conclusion est que plus souvent qu'autrement, si vous utilisez l'API de manière incorrecte, vous voyez un comportement incorrect de seuil. Utilisez correctement et vous devriez voir le comportement correct:
public static void main (String[] args) {
Byte b1=127;
Byte b2=127;
Short s1=127; //incorrect should use Byte
Short s2=127; //incorrect should use Byte
Short s3=128;
Short s4=128;
Integer i1=127; //incorrect should use Byte
Integer i2=127; //incorrect should use Byte
Integer i3=128;
Integer i4=128;
Integer i5=32767; //incorrect should use Short
Integer i6=32767; //incorrect should use Short
Long l1=127L; //incorrect should use Byte
Long l2=127L; //incorrect should use Byte
Long l3=13267L; //incorrect should use Short
Long l4=32767L; //incorrect should use Short
Long l5=2147483647L; //incorrect should use Integer
Long l6=2147483647L; //incorrect should use Integer
Long l7=2147483648L;
Long l8=2147483648L;
System.out.print(b1==b2); //true (incorrect) Used API correctly
System.out.print(s1==s2); //true (incorrect) Used API incorrectly
System.out.print(i1==i2); //true (incorrect) Used API incorrectly
System.out.print(l1==l2); //true (incorrect) Used API incorrectly
System.out.print(s3==s4); //false (correct) Used API correctly
System.out.print(i3==i4); //false (correct) Used API correctly
System.out.print(i5==i6); //false (correct) Used API correctly
System.out.print(l3==l4); //false (correct) Used API correctly
System.out.print(l7==l8); //false (correct) Used API correctly
System.out.print(l5==l6); //false (correct) Used API incorrectly
}