Je sais que c'est probablement très stupide, mais de nombreux endroits affirment que la classe Integer en Java est immuable, mais le code suivant:
Integer a=3;
Integer b=3;
a+=b;
System.out.println(a);
S'exécute sans problème en donnant le résultat (attendu) 6. Donc effectivement la valeur de a a changé. Cela ne signifie-t-il pas qu'Integer est mutable? Question secondaire et un peu hors-sujet: "Les classes immuables n'ont pas besoin de constructeurs de copie". Quelqu'un veut-il expliquer pourquoi?
java
immutability
mutable
K.Steff
la source
la source
Réponses:
Immuable ne signifie pas que cela
a
ne peut jamais égaler une autre valeur. Par exemple,String
est immuable aussi, mais je peux toujours le faire:str
n'a pas été changé, plutôtstr
s'agit un objet complètement nouvellement instancié, tout comme le vôtreInteger
. Donc, la valeur dea
n'a pas muté, mais elle a été remplacée par un objet complètement nouveau, ienew Integer(6)
.la source
+=
opération.Integer.valueOf(int)
et cette méthode maintient un cache d'Integer
objets. Ainsi, le résultat de+=
sur uneInteger
variable pourrait être un objet qui existait auparavant (ou il pourrait même être le même objet ... dans le cas dea += 0
).a
est une "référence" à un nombre entier (3), votre raccourcia+=b
signifie vraiment faire ceci:Donc non, les entiers ne sont pas modifiables, mais les variables qui pointent vers eux sont *.
* Il est possible d'avoir des variables immuables, celles-ci sont désignées par le mot-clé
final
, ce qui signifie que la référence ne peut pas changer.la source
Vous pouvez déterminer que l'objet a changé en utilisant
System.identityHashCode()
(Une meilleure façon est d'utiliser plain,==
mais ce n'est pas aussi évident que la référence plutôt que la valeur a changé)impressions
Vous pouvez voir que l '«id» sous-jacent de l'objet auquel
a
fait référence a changé.la source
À la question initiale posée,
L'entier est immuable, donc ce qui s'est passé ci-dessus est que «a» a été changé en une nouvelle référence de valeur 6. La valeur initiale 3 est laissée sans référence dans la mémoire (elle n'a pas été modifiée), elle peut donc être récupérée.
Si cela arrive à une chaîne, elle restera dans le pool (dans l'espace PermGen) pendant une période plus longue que les entiers car elle s'attend à avoir des références.
la source
Oui Integer est immuable.
A est une référence qui pointe vers un objet. Lorsque vous exécutez un + = 3, cela réaffecte A pour référencer un nouvel objet Integer, avec une valeur différente.
Vous n'avez jamais modifié l'objet d'origine, vous avez plutôt pointé la référence vers un objet différent.
Découvrez la différence entre les objets et les références ici .
la source
Immuable ne signifie pas que vous ne pouvez pas modifier la valeur d'une variable. Cela signifie simplement que toute nouvelle affectation crée un nouvel objet (lui attribue un nouvel emplacement mémoire), puis la valeur lui est affectée.
Pour comprendre cela par vous-même, effectuez une affectation entière dans une boucle (avec un entier déclaré en dehors de la boucle) et regardez les objets en direct en mémoire.
La raison pour laquelle le constructeur de copie n'est pas nécessaire pour les objets immuables est le simple bon sens. Étant donné que chaque affectation crée un nouvel objet, la langue crée déjà techniquement une copie, vous n'avez donc pas à créer une autre copie.
la source
La raison en est qu'il est rarement nécessaire de copier (ou même de copier) une instance d'une classe immuable. La copie de l'objet doit être "la même que" l'original, et si elle est la même, il ne devrait pas être nécessaire de la créer.
Il y a cependant quelques hypothèses sous-jacentes:
Cela suppose que votre application ne donne aucune signification à l'identité d'objet des instances de la classe.
Il suppose que la classe a été surchargée
equals
ethashCode
qu'une copie d'une instance serait "identique à" l'original ... selon ces méthodes.L'une ou l'autre de ces hypothèses ou les deux pourraient être fausses, ce qui pourrait justifier l'ajout d'un constructeur de copie.
la source
C'est comme ça que je comprends immuable
Si int pouvait muter, "a" afficherait 8 mais ce n'est pas le cas car il est immuable, c'est pourquoi il est 3. Votre exemple est juste une nouvelle affectation.
la source
Je peux préciser que Integer (et d'autres de ses croyances comme Float, Short, etc.) sont immuables par un simple exemple de code:
Le résultat arrive au Hi There 100 au lieu du résultat attendu (dans le cas où sb et i sont des objets mutables) Hi There 1000
Cela montre que l'objet créé par i dans main n'est pas modifié, alors que le sb est modifié.
Ainsi, StringBuilder a démontré un comportement modifiable mais pas Integer.
Donc Integer est immuable. Par conséquent prouvé
la source
private void doStringBuilder(StringBuilder sb){ sb = new StringBuilder(); }
alorssb
est inchangée.private void doInteger(Integer i){ System.out.println( i == 100 ); i=1000; System.out.println( i == 100 ); }
La sortie est:
Salut au revoir 1000 5000 1000 5000 d a
Donc char est mutable, String Integer et int sont immuables.
la source