9
votes

Integer i = 3 vs entier i = neuf entier (3)

Je comparais 2 pièces de code. Premier xxx p> second, xxx

J'ai doute que dans la première extraite pourquoi i == j est Être imprimé? Les références ne devraient-elles pas être différentes?


7 commentaires

Quelque chose à faire avec référence, nouveaux, objets, comparer des adresses mémoire #idk # cis20 ... quelque chose


== Comparez les références non des valeurs, lorsque vous affectez. Dans le cas du poing i , j points vers les mêmes entiers en mémoire. Où dans le deuxième cas en utilisant nouveau, vous créez deux nouvel exemple d'integer d'objet avec la même valeur 3.


Ce n'est pas un duplicata de la question liée. Notez que la question a été fermée comme une "question non réelle" en raison d'une prémisse erronée que neuf entier (1) == nouveau entier (1) , qui n'est pas vrai.


@Johnkugelman - C'est la même question, juste inversé, que la réponse à cette question couvre.


C'est pas la même question. Jon Skeet a posté une réponse similaire mais la question est assez différente!


@Johnkugelman: D'accord, bien que cela m'amuse que ma réponse dans la question liée fait répond à cette question ... mais pas aussi (imo) que ma réponse dans celui-ci :)


@AMR: Non, ce n'est pas le cas du tout.


9 Réponses :


0
votes

Parce que dans le second morceau de code de code, votre premier entier est en boîte automatique tandis que la seconde n'est pas.

Cela signifie qu'une nouvelle instance d'entier est en cours de création à la volée. Ces 2 instances d'objet sont différentes. La vérification de l'égalité reviendra de faux là car les deux instances sont en réalité différentes pièces de mémoire.


4 commentaires

Non, c'est le document premier code qui utilise de l'autoboxe dans les deux cas; La seconde l'utilise uniquement pour la première valeur.


Je faisais référence au premier entier, pas la seconde.


C'était extrêmement flou. C'est toujours pas clair de cette réponse pourquoi le premier morceau de code imprime "i == j", car vous n'avez rien expliqué à propos de la nature cache de la boxe.


Oui, ce n'était pas clair Je suppose. Et je suis d'accord sur la négligence d'expliquer de manière adéquate de la boxe automatique. Le tien est beaucoup mieux.



1
votes

Non, ils ne devraient pas, car Java peut utiliser des objets entiers pré-fabriqués pour de petits nombres lors de l'autoboxage.


0 commentaires

6
votes

Les entiers de pools Java entre -128 et 127 et donc les deux références sont les mêmes. XXX PRE>

Il résulte de l'autoboxage et 3 est converti en entier 3. Pour que je puisse faire référence à un Objet entier qui est dans une piscine constante, maintenant lorsque vous le faites J = 3, la même référence que celle de I est attribuée à j. P>

alors qu'après le code ci-dessous: P>

Integer i=3;
Integer j=new Integer(3);
if(i==j)
   System.out.println("i==j"); // **does not print**


1 commentaires

... dans le premier cas.



0
votes

Interprète / JIT Optimizer peut mettre les 3 3 dans la même boîte. Mais si vous forcez un "nouveau" alors vous obtenez une autre adresse.

Essayez xxx

puis voir l'adresse de j changée pour la première version.


0 commentaires

18
votes

C'est à voir avec la façon dont la boxe fonctionne. De Section JLS 5.1.7 :

Si la valeur P étant en boîte est vraie, false, un octet ou un caractère dans la plage \ u0000 à \ u007f, ou un nombre int ou court entre -128 et 127 (inclus), puis laisser r1 et r2 être Les résultats de toutes les conversions de boxe de p. C'est toujours le cas que R1 == R2.

Fondamentalement, une implémentation Java doit mettre en cache les représentations en boîte pour des valeurs de manière appropriée et mai cache plus. L'opérateur == ne fait que comparer les références, de sorte qu'il détecte spécifiquement si les deux variables se rapportent au même objet. Dans le second code snippet ils vont certainement pas, comme new Integer (3) est certainement pas la même référence que tout précédemment créé un ... il crée toujours un nouvel objet.

En raison des règles ci-dessus, ce code doit toujours donner le même résultat: xxx

alors que cela pourrait aller de toute façon: xxx


9 commentaires

Vous devriez expliquer == comparaison.


Pourquoi cela est-il descendu?


@William Morrison: En désaccord. L'OP obtient déjà déjà que == est l'égalité de référence. La question est qu'il s'attend à tort à tort que les références étaient différentes (c'est-à-dire que le concept manquant est "interne" pour certaines primitives, pas pas de grokking == ).


Je ne joue avec personne. Peut-être que je me trompe. Je préfère des explications excessivement approfondies ...


@WilliamMorison: La réponse éditée est-elle meilleure? J'ai inclus == comportement en même temps que d'expliquer que nouvel entiers (3) créerait définitivement un nouvel objet. (Malgré les autres commentaires, je n'ai aucun problème à inclure une explication supplémentaire ici ...)


@Williammorison, selon vous, toutes les explications devraient commencer par: "Au début, il y avait le mot ..."


Oui j'aime beaucoup cette réponse maintenant, excellent travail.


Très intéressant que la mise en commun est définie dans la spécification JLS, étant donné que pour l'affaire d'entier, elle est faite via la classe d'entier et non la JVM.


Si Jon Skeet répond à votre question, vous devez seulement vous dire merci, car c'est sûrement correct, ne dites pas "tu devrais ..." lol



0
votes

dans un similaire em> la mode aux chaînes, lorsque l'autoboxage est utilisé, par exemple dans

Integer i = 3;
Integer j = 3;


0 commentaires

3
votes

Je doute que dans le premier extrait, pourquoi je suis imprimé? Les références ne devraient-elles pas être différentes?

car, xxx

utilise à l'intérieur Valeur d'entier de () pour effectuer autoboxing . Et Oracle Doc affirment à propos de ValueOf () Méthode:

retourne une instance d'intique représentant la valeur INT spécifiée. Si un La nouvelle instance entier n'est pas requise, cette méthode devrait généralement être utilisé de préférence au constructeur entier (int), comme cette méthode est susceptibles de donner une performance de l'espace et du temps de manière significativement meilleure mise en cache des valeurs fréquemment demandées. cette méthode sera toujours en cache valeurs dans la plage -128 à 127, inclusive et peut cacher d'autres valeurs en dehors de cette gamme.

car la valeur 3 est donc mis en cache, les deux variables i et j font référence au même objet. Donc, i == j renvoie true . Valeur en IntegerOf () Utilise motif voleur . < / blockquote>


0 commentaires

3
votes
Integer i=300;
Integer j=300;
if(i!=j)System.out.println("i!=j"); // prints i!=j

2 commentaires

Entier La mise en commun n'est pas effectué par la JVM. C'est entièrement fait par entier . Voir le code source d'entier .


@Stevekuo je viens de vérifier integer.valueof () et oui la plage est délimitée par entier entre -128 sur integercache.high (127). J'ai corrigé ma réponse. Merci.



0
votes

Dans la pièce de code suivante: xxx

ici, "==" compare la référence les unes avec les autres plutôt que la valeur. Donc, ITeger I et J les deux se réfèrent à la même référence dans la mémoire.

en suivant la pièce de code suivante: xxx

la référence aux deux valeurs sont modifiés car "j 'est nouvellement créé objet / référence d'entier en mémoire, tandis que" i' est simplement référence à une valeur.

Par conséquent, la sortie du 1er code est "i == j" et 2e Le code n'a pas de sortie.

espère que cela aide.


0 commentaires