114 votes

Est Immuable Entier

Je sais que c'est sans doute très bête, mais beaucoup de lieux revendication que l'Entier de la classe en Java est immuable, mais le code suivant:

Integer a=3;
Integer b=3;
a+=b;
System.out.println(a);

S'exécute sans mal à donner le (attendues) résultat 6. Donc, effectivement la valeur de a changé. Ne veut pas dire que Entier est muable? Question secondaire et un peu hors-sujet: "Immuable classes n'ont pas besoin de copier les constructeurs". Quelqu'un veut bien expliquer pourquoi?

102voto

Travis Webb Points 5765

Immuable ne signifie pas qu' a ne peut jamais égale à une autre valeur. Par exemple, String est immuable trop, mais je peux encore le faire:

String str = "hello";
// str == "hello"
str = str + "world";
// now str == "helloworld"

Alors, quel est-il arrivé? Depuis String est immuable, clairement str n'a pas été modifié. Mais il est maintenant égale à quelque chose de différent. C'est parce qu' str est maintenant complètement un objet nouvellement instancié, tout comme votre Integer est. Ainsi, la valeur de a n'ont pas muté, en soi, mais il a été remplacé par un tout nouvel objet, c - new Integer(6).

59voto

Mark Elliot Points 31871

a est une "référence" à certains Integer(3), votre texte abrégé a+=b signifie vraiment ce faire:

a = new Integer(3 + 3)

Donc non, les Entiers ne sont pas mutables, mais les variables qui pointent vers eux sont*.

*Il est possible d'avoir immuable de variables, qui sont désignées par le mot-clé final, ce qui signifie que la référence ne peut pas changer.

final Integer a = 3;
final Integer b = 3;
a += b; // this line will throw an exception, the variable `a` is immutable, too.

23voto

Peter Lawrey Points 229686

Vous pouvez déterminer que l'objet a changé à l'aide de System.identityHashCode() (Une meilleure façon est d'utiliser simplement de l' == cependant ce n'est pas aussi évident que la référence plutôt que la valeur a changé)

Integer a = 3;
System.out.println("before a +=3; a="+a+" id="+Integer.toHexString(System.identityHashCode(a)));
a += 3;
System.out.println("after a +=3; a="+a+" id="+Integer.toHexString(System.identityHashCode(a)));

imprime

before a +=3; a=3 id=70f9f9d8
after a +=3; a=6 id=2b820dda

Vous pouvez voir le "id" de l'objet a se réfère à a changé.

11voto

Harsha Points 177

Pour la première question posée,

Integer a=3;
Integer b=3;
a+=b;
System.out.println(a);

Entier est immuable, de sorte que ce qui s'est passé ci-dessus est 'a' a changé pour une nouvelle référence de la valeur 6. La valeur initiale de 3 est à gauche avec pas de référence dans la mémoire (il n'a pas été changé), de sorte qu'il peut être nettoyée.

Si cela se produit à une Chaîne, elle permet de conserver dans la piscine (en PermGen space) pour la période plus longue que les nombres Entiers comme s'il s'attend à avoir des références.

2voto

Stephen C Points 255558

"Immuable classes n'ont pas besoin de copier les constructeurs". Quelqu'un veut bien expliquer pourquoi?

La raison en est qu'il est rarement nécessaire de copier (ou même n'importe quel point dans la copie) une instance d'un immuable de la classe. La copie de l'objet doit être "la même chose que l'original, et si c'est le même, il devrait y avoir aucun besoin de le créer.

Il y a quelques hypothèses sous-jacentes si:

  • Il suppose que votre demande n'a pas de sens sur l'identité de l'objet d'instances de la classe.

  • Il suppose que la classe a surchargé equals et hashCode , de sorte qu'une copie d'un exemple serait "la même chose que" l'original ... selon ces méthodes.

L'une ou les deux de ces hypothèses, il pourrait être faux, et qui peuvent justifier l'ajout d'un constructeur de copie.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X