Cela pourrait être la question la plus stupide jamais posée, mais je pense que c'est assez déroutant pour un débutant Java.
- Quelqu'un peut-il clarifier ce que l'on entend par immuable ?
- Pourquoi un
String
immuable? - Quels sont les avantages / inconvénients des objets immuables?
- Pourquoi devrait-
StringBuilder
on préférer un objet mutable tel que String et vice-versa?
Un bel exemple (en Java) sera vraiment apprécié.
java
string
immutability
ashokgelal
la source
la source
Réponses:
Immuable signifie qu'une fois que le constructeur d'un objet a terminé son exécution, cette instance ne peut plus être modifiée.
C'est utile car cela signifie que vous pouvez passer des références à l'objet autour, sans vous soucier que quelqu'un d'autre va changer son contenu. Surtout lorsqu'il s'agit de simultanéité, il n'y a pas de problème de verrouillage avec des objets qui ne changent jamais
par exemple
Foo
n'a pas à craindre que l'appelantgetValue()
ne change le texte de la chaîne.Si vous imaginez une classe similaire à
Foo
, mais avec unStringBuilder
plutôt queString
comme un membre, vous pouvez voir qu'un appelant àgetValue()
pourrait modifier l'StringBuilder
attribut d'uneFoo
instance.Méfiez-vous également des différents types d'immuabilité que vous pourriez trouver: Eric Lippert a écrit un article de blog à ce sujet. Fondamentalement, vous pouvez avoir des objets dont l'interface est immuable mais dans les coulisses de l'état privé mutable réel (et ne peut donc pas être partagé en toute sécurité entre les threads).
la source
Un objet immuable est un objet dans lequel les champs internes (ou du moins, tous les champs internes qui affectent son comportement externe) ne peuvent pas être modifiés.
Les chaînes immuables présentent de nombreux avantages:
Performances: effectuez l'opération suivante:
Le C sous-jacent de la méthode substring () est probablement quelque chose comme ceci:
Notez qu'aucun des caractères ne doit être copié! Si l'objet String était modifiable (les caractères pourraient changer plus tard), vous devrez alors copier tous les caractères, sinon les modifications apportées aux caractères de la sous-chaîne seront reflétées ultérieurement dans l'autre chaîne.
Concurrence: si la structure interne d'un objet immuable est valide, elle le sera toujours. Il n'y a aucune chance que différents threads puissent créer un état non valide au sein de cet objet. Par conséquent, les objets immuables sont Thread Safe .
Collecte des ordures: il est beaucoup plus facile pour le garbage collector de prendre des décisions logiques concernant les objets immuables.
Cependant, il y a aussi des inconvénients à l'immuabilité:
Performance: Attendez, je pensais que vous aviez dit que la performance était un avantage de l'immuabilité! Eh bien, c'est parfois, mais pas toujours. Prenez le code suivant:
Les deux lignes remplacent toutes les deux le quatrième caractère par la lettre "a". Non seulement le deuxième morceau de code est plus lisible, mais il est plus rapide. Regardez comment vous devriez faire le code sous-jacent pour foo. Les sous-chaînes sont faciles, mais maintenant parce qu'il y a déjà un caractère à l'espace cinq et que quelque chose d'autre fait référence à foo, vous ne pouvez pas simplement le changer; vous devez copier la chaîne entière (bien sûr, certaines de ces fonctionnalités sont abstraites en fonctions dans le vrai C sous-jacent, mais le point ici est de montrer le code qui est exécuté tout en un seul endroit).
Notez que concaténer est appelé deux fois, ce qui signifie que la chaîne entière doit être bouclée! Comparez cela au code C de l'
bar
opération:L'opération de chaîne mutable est évidemment beaucoup plus rapide.
En conclusion: dans la plupart des cas, vous voulez une chaîne immuable. Mais si vous avez besoin de faire beaucoup d'ajout et d'insertion dans une chaîne, vous avez besoin de la mutabilité pour la vitesse. Si vous souhaitez bénéficier des avantages de la sécurité et de la récupération de place de la concurrence, la clé consiste à conserver vos objets mutables en local par rapport à une méthode:
Étant donné que l'
mutable
objet est une référence locale, vous n'avez pas à vous soucier de la sécurité des accès concurrents (un seul thread le touche). Et comme il n'est référencé nulle part ailleurs, il est uniquement alloué sur la pile, il est donc désalloué dès que l'appel de fonction est terminé (vous n'avez pas à vous soucier du garbage collection). Et vous bénéficiez de tous les avantages de performance de la mutabilité et de l'immuabilité.la source
Passing pointers because Java is pass-by-reference
La java n'est-elle pas «pass-by-value»?En fait, String n'est pas immuable si vous utilisez la définition wikipedia suggérée ci-dessus.
L'état de la chaîne change la post-construction. Jetez un œil à la méthode hashcode (). La chaîne met en cache la valeur de hashcode dans un champ local mais ne la calcule qu'au premier appel de hashcode (). Cette évaluation paresseuse de hashcode place String dans une position intéressante en tant qu'objet immuable dont l'état change, mais il ne peut pas être observé comme ayant changé sans utiliser la réflexion.
Alors peut-être que la définition d'immuable devrait être un objet qui ne peut pas être observé comme ayant changé.
Si l'état change dans un objet immuable après sa création mais que personne ne peut le voir (sans réflexion), l'objet est-il toujours immuable?
la source
Les objets immuables sont des objets qui ne peuvent pas être modifiés par programme. Ils sont particulièrement adaptés aux environnements multithreads ou à d'autres environnements où plusieurs processus sont capables de modifier (muter) les valeurs d'un objet.
Juste pour clarifier, cependant, StringBuilder est en fait un objet modifiable, pas immuable. Une chaîne Java régulière est immuable (ce qui signifie qu'une fois qu'elle a été créée, vous ne pouvez pas modifier la chaîne sous-jacente sans changer l'objet).
Par exemple, disons que j'ai une classe appelée ColoredString qui a une valeur String et une couleur String:
Dans cet exemple, ColoredString est censé être mutable car vous pouvez modifier (muter) l'une de ses propriétés clés sans créer de nouvelle classe ColoredString. La raison pour laquelle cela peut être mauvais est, par exemple, supposons que vous avez une application GUI qui a plusieurs threads et que vous utilisez ColoredStrings pour imprimer des données dans la fenêtre. Si vous avez une instance de ColoredString qui a été créée en tant que
Vous vous attendez alors à ce que la chaîne soit toujours "Bleue". Si un autre thread, cependant, s'est emparé de cette instance et a appelé
Vous auriez soudainement, et probablement de manière inattendue, maintenant une chaîne "Rouge" quand vous en vouliez une "Bleue". Pour cette raison, les objets immuables sont presque toujours préférés lors du passage d'instances d'objets autour. Lorsque vous avez un cas où des objets modifiables sont vraiment nécessaires, vous gardez généralement l'objet en ne faisant passer que des copies de votre champ de contrôle spécifique.
Pour récapituler, en Java, java.lang.String est un objet immuable (il ne peut pas être modifié une fois qu'il a été créé) et java.lang.StringBuilder est un objet modifiable car il peut être modifié sans créer de nouvelle instance.
la source
String s1 = "Old string";
Chaîne s2 = s1;
s1 = "Nouvelle chaîne";
la source
"immuable" signifie que vous ne pouvez pas modifier la valeur. Si vous avez une instance de la classe String, toute méthode que vous appelez qui semble modifier la valeur créera en fait une autre String.
Pour conserver les modifications, vous devriez faire quelque chose comme ceci foo = foo.sustring (3);
Immuable vs mutable peut être drôle lorsque vous travaillez avec des collections. Réfléchissez à ce qui se passera si vous utilisez un objet mutable comme clé pour la carte, puis modifiez la valeur (conseil: pensez à
equals
ethashCode
).la source
java.time
Il peut être un peu tard, mais pour comprendre ce qu'est un objet immuable, considérons l'exemple suivant de la nouvelle API de date et d'heure Java 8 ( java.time ). Comme vous le savez probablement, tous les objets de date de Java 8 sont immuables, donc dans l'exemple suivant
Production:
Cela imprime la même année que la date initiale car le
plusYears(2)
retourne un nouvel objet, donc l'ancienne date est toujours inchangée car c'est un objet immuable. Une fois créé, vous ne pouvez plus le modifier et la variable de date pointe toujours dessus.Ainsi, cet exemple de code doit capturer et utiliser le nouvel objet instancié et renvoyé par cet appel à
plusYears
.la source
J'aime vraiment l'explication du guide d'étude SCJP Sun Certified Programmer for Java 5 .
la source
Les objets qui sont immuables ne peuvent pas voir leur état changé après avoir été créés.
Il y a trois raisons principales d'utiliser des objets immuables chaque fois que vous le pouvez, ce qui contribuera à réduire le nombre de bogues que vous introduisez dans votre code:
Il existe également d'autres optimisations que vous pourriez être en mesure de faire dans le code lorsque vous savez que l'état d'un objet est immuable - la mise en cache du hachage calculé, par exemple - mais ce sont des optimisations et donc pas si intéressantes.
la source
Une signification a à voir avec la façon dont la valeur est stockée dans l'ordinateur, pour une chaîne .Net par exemple, cela signifie que la chaîne en mémoire ne peut pas être modifiée, lorsque vous pensez que vous la changez, vous créez en fait une nouvelle chaîne en mémoire et en pointant la variable existante (qui n'est qu'un pointeur vers la collection réelle de caractères ailleurs) vers la nouvelle chaîne.
la source
s1="Hi"
: un objet as1
été créé avec une valeur "Hi".s2=s1
: un objets2
est créé en référence à l'objet s1.s1="Bye"
: las1
valeur de l'objet précédent ne change pas cars1
a le type String et le type String est un type immuable, à la place le compilateur crée un nouvel objet String avec la valeur "Bye" et y faits1
référence. ici lorsque nous imprimons las2
valeur, le résultat sera "Hi" et non "Bye" cars2
référencé à l's1
objet précédent qui avait une valeur "Hi".la source
Immuable signifie qu'une fois l'objet créé, aucun de ses membres ne changera.
String
est immuable car vous ne pouvez pas modifier son contenu. Par exemple:Dans le code ci-dessus, la chaîne s1 n'a pas changé, un autre objet (
s2
) a été créé à l'aides1
.la source
Immuable signifie simplement immuable ou non modifiable. Une fois l'objet chaîne créé, ses données ou son état ne peuvent pas être modifiés
Prenons l'exemple ci-dessous,
Prenons l'idée en considérant le diagramme ci-dessous,
Dans ce diagramme, vous pouvez voir un nouvel objet créé comme "Future World". Mais ne changez pas "Future".
Because String is immutable
.s
, font toujours référence à "Future". Si vous devez appeler "Future World",Pourquoi les objets chaîne sont-ils immuables en Java?
la source
Une fois instancié, ne peut être modifié. Considérez une classe dont une instance pourrait être utilisée comme clé pour une table de hachage ou similaire. Découvrez les meilleures pratiques Java.
la source
Objets immuables
Un objet est considéré comme immuable si son état ne peut pas changer après sa construction. La confiance maximale dans les objets immuables est largement acceptée comme une stratégie solide pour créer un code simple et fiable.
Les objets immuables sont particulièrement utiles dans les applications simultanées. Puisqu'ils ne peuvent pas changer d'état, ils ne peuvent pas être corrompus par une interférence de thread ou observés dans un état incohérent.
Les programmeurs hésitent souvent à utiliser des objets immuables, car ils s'inquiètent du coût de création d'un nouvel objet par opposition à la mise à jour d'un objet en place. L'impact de la création d'objets est souvent surestimé et peut être compensé par certaines des efficacités associées aux objets immuables. Il s'agit notamment de la réduction des frais généraux en raison de la collecte des ordures et de l'élimination du code nécessaire pour protéger les objets mutables contre la corruption.
Les sous-sections suivantes prennent une classe dont les instances sont mutables et en dérivent une classe avec des instances immuables. Ce faisant, ils donnent des règles générales pour ce type de conversion et démontrent certains des avantages des objets immuables.
La source
la source
Comme la réponse acceptée ne répond pas à toutes les questions. Je suis obligé de donner une réponse après 11 ans et 6 mois.
J'espère que vous vouliez dire un objet immuable (car nous pourrions penser à une référence immuable ).
Un objet est immuable : si une fois créé, il représente toujours la même valeur (n'a pas de méthode pour changer la valeur).
Respectez la définition ci-dessus qui pourrait être vérifiée en consultant le code source de Sting.java .
plus sûr contre les bugs.
plus facile à comprendre.
et plus prêt pour le changement.
Limiter la question Pourquoi avons-nous besoin du StringBuilder mutable dans la programmation? Une utilisation courante consiste à concaténer un grand nombre de chaînes ensemble, comme ceci:
En utilisant des chaînes immuables, cela fait beaucoup de copies temporaires - le premier numéro de la chaîne ("0") est en fait copié n fois au cours de la construction de la chaîne finale, le deuxième nombre est copié n-1 fois, et ainsi sur. En fait, il en coûte O (n2) juste pour faire toute cette copie, même si nous n'avons concaténé que n éléments.
StringBuilder est conçu pour minimiser cette copie. Il utilise une structure de données interne simple mais intelligente pour éviter toute copie jusqu'à la fin, lorsque vous demandez la chaîne finale avec un appel toString ():
Obtenir de bonnes performances est l'une des raisons pour lesquelles nous utilisons des objets mutables. Un autre est le partage pratique: deux parties de votre programme peuvent communiquer plus facilement en partageant une structure de données mutable commune.
Plus d'informations peuvent être trouvées ici: https://web.mit.edu/6.005/www/fa15/classes/09-immutability/#useful_immutable_types
la source
Un objet immuable est celui que vous ne pouvez pas modifier après l'avoir créé. Un exemple typique sont les littéraux de chaîne.
Le langage de programmation AD, qui devient de plus en plus populaire, a une notion d '"immuabilité" à travers un mot-clé "invariant". Consultez cet article de Dr.Dobb à ce sujet - http://dobbscodetalk.com/index.php?option=com_myblog&show=Invariant-Strings.html&Itemid=29 . Cela explique parfaitement le problème.
la source