Le cas de test suivant réussira:
@Test
public void assignWrapperTest() {
System.out.printf("\nassign - %s\n", "wrapper");
Integer a = 1000;
Integer b = a;
System.out.printf("a = %d, b = %d\n", a, b);
Assert.assertEquals(a, b);
Assert.assertSame(a, b); // a, b are the same object,
a++;
System.out.printf("a = %d, b = %d\n", a, b);
Assert.assertNotEquals(a, b);
Assert.assertNotSame(a, b); // a, b are not the same object, any more,
}
Alors:
a
est modifié par ++
.b
reste le même.Les questions sont:
b = a
juste assigner la valeur de référence à droite, ils font référence au même objet, à ce stade il n'y a qu'un seul objet, non?++
a créé un nouvel objet Integer et l'a affecté automatiquement à la variable d'origine? Si tel est le cas, cela signifie-t-il que a
pointe maintenant vers un objet différent?b
indique-t-il toujours l'original?a++;
Étant donné que a
est une Integer
, cela revient à:
a = Integer.valueOf(a.intValue() + 1);
est-ce que cela signifie que
++
a créé un nouvel objet Integer
Peut-être, mais pas nécessairement: Integer.valueOf
réutilisera une valeur mise en cache; une nouvelle valeur ne sera créée qu'en dehors de la plage mise en cache (qui est au moins -128..127).
Si nous regardons le Byte code
de a++
; Cela ressemble à quelque chose comme ci-dessous:
9: aload_1
10: invokevirtual #22 // Method Java/lang/Integer.intValue:()I
13: iconst_1
14: iadd
15: invokestatic #16 // Method Java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
18: astore_1
Les instructions sont donc comme obtenir la intValue()
de a
puis increment
puis appeler Integer#valueOf
sur la valeur incrémentée et Integer # valueOf créer un nouvel objet.
a++
fait effectivement a=a+1
(en ignorant la logique pour le convertir en Integer
). L'expression a+1
correspond à une nouvelle int
et est affectée à a
.b
n'a pas été touchée par les opérations précédentes et par conséquent, elle pointe toujours vers le même objet.Le point clé ici est que Integer
est immutable
.
Si l'opérande est modifiable, comme un opérateur int
, ++
, ajoutez simplement 1
à la valeur d'origine in place .
Pour Integer
c'est différent. Avec a++
, une nouvelle instance de Integer
est créée et sa valeur provient de l'ajout d'un 1
à l'objet Integer d'origine auquel a
et b
pointent, puis a
est réaffecté à ce nouvel objet. b
fait toujours référence à l'objet Integer d'origine, donc a
et b
ne sont plus les mêmes.