Dans la classe ci-dessous, j'ai essayé de comparer la classe wrapper avec la primitive mais les résultats sont différents.
J'ai vérifié les liens suivants liens :
La question la plus intéressante est pourquoi
new Object();
devrait être requis pour créer une instance unique à chaque fois? je. e. pourquoinew Object();
n'est-il pas autorisé à mettre en cache? La réponse est les appelswait(...)
etnotify(...)
. La mise en cache de nouveauxObject()
s entraînerait une synchronisation incorrecte des threads alors qu'ils ne le devraient pas.
S'il y a un nouvel objet, comment a
et c
sont-ils égaux?
Si b
est égal à c
et c
est égal à a
, alors a
doit être égal à b
. Mais dans le cas suivant, j'ai eu a != c
.
S'il vous plaît, expliquez.
class WrapperCompare {
public static void main (String args[]) {
Integer a = new Integer(10);
Integer b = 10;
int c=10;
System.out.println(b==c); //true
System.out.println(a==b); //false
System.out.println(a==c); //true
}
}
Mise à jour: En se référant à ce lien mise en cache entière .
Fondamentalement, la classe Integer conserve un cache d'instances Integer dans la plage de -128 à 127, et tous les autoboxing, littéraux et utilisations de Integer.valueOf () renverront des instances de ce cache pour la plage qu'elle couvre.
Dans ce cas, toutes les déclarations doivent donc être vraies.
Lorsque vous comparez Integer
et int
avec ==
, Il doit convertir le Integer
en un int
. C'est ce qu'on appelle unboxing .
Voir JLS§5.1.8 :
Si
r
est une référence de typeInteger
, alors conversion unboxing convertitr
enr.intValue()
À ce stade, vous comparez int
à int
. Et les primitives n'ont aucune notion d'instances, elles se réfèrent toutes à la même valeur . En tant que tel, le résultat est true
.
Donc, le code réel que vous avez est
a.intValue() == c
conduisant à une comparaison de 10 == 10
, les deux valeurs int
, plus d'instances Integer
.
Vous pouvez voir que new Integer(...)
crée en effet de nouvelles instances, lorsque vous comparez Integer
vs Integer
. Vous l'avez fait dans a == b
.
Le constructeur new Integer(...)
est obsolète . Vous devriez plutôt utiliser Integer#valueOf
, Il est potentiellement plus rapide et utilise également un cache interne. De la documentation :
Renvoie une instance de
Integer
représentant la valeurint
spécifiée. Si une nouvelle instance entière n'est pas requise, cette méthode doit généralement être utilisée de préférence au constructeurInteger(int)
, car cette méthode est susceptible de donner nettement mieux espace et temps performances par mise en cache valeurs fréquemment demandées . Cette méthode mettra toujours en cache les valeurs dans la plage-128
À127
, Inclusivement, et peut mettre en cache d'autres valeurs en dehors de cette gamme.
La mise en cache est importante à noter ici, car elle renvoie à ==
À nouveau vrai (pour les valeurs mises en cache):
Integer first = Integer.valueOf(10);
Integer second = Integer.valueOf(10);
System.out.println(first == second); // true
La mise en cache est garantie pour les valeurs comprises entre -128
Et +127
, Mais peut également être utilisée pour d'autres.
Notez également que votre b
sort réellement du cache, car
Integer b = 10;
// same as
Integer b = Integer.valueOf(10);
// and not
Integer b = new Integer(10);
Ainsi la boxe passe par le cache de Integer
(voir JLS§5.1.7 ).