Donnez-moi s'il vous plaît exemples où je pouvais voir les avantages des objets immuables. Les informations que j'ai trouvées sur Internet sont concentrées dans des threads. Je ne sais pas encore des threads. serait génial si les exemples utiliseraient des principes simples p>
8 Réponses :
Ce n'est pas un concept qui peut être utilement expliqué avec des exemples. L'avantage des objets immuables est que vous connaissez que leurs données ne peuvent pas changer, vous n'avez donc pas à vous soucier de cela. Vous pouvez les transmettre librement sans avoir à vous rappeler si une méthode que vous les transmettez pour les modifier d'une manière dont votre code n'est pas prêt à gérer. Cela facilite le travail avec des données immuables. p>
Avec plusieurs threads, cet avantage est tout simplement plus important, car les bogues basés sur plusieurs threads changent de données de manière à ne pas être modifiés ne sont généralement pas reproductibles - ils dépendent donc du moment et parfois parfois et parfois pas, ce qui les rend très difficile à analyser et à corriger. p>
Les objets immuables sont utiles lorsque des objets sont généralement partagés - pas seulement avec une filetage, mais dans des programmes à une seule fois si un objet a de nombreux clients. P>
Par exemple, Les données immuables ont également des implications de sécurité. Par exemple, un jeton de sécurité associé à un utilisateur doit être immuable, sinon un programme de voyou pourrait facilement modifier l'utilisateur associé à ce jeton. P> String code> est probablement l'objet immuable le plus utilisé en Java. Il est immuable d'empêcher les utilisateurs de cette chaîne de changer son contenu. Si chaîne code> était mutable, cela signifierait que chaque utilisateur devrait créer une copie unique de cette chaîne pour vous assurer que personne d'autre ne le modifie. p>
L'idée principale ici est de faire en sorte que vos classes soient en sécurité en utilisant des objets immuables. Je pense que ce article est une bonne lecture à ce sujet. p>
J'espère que cela vous aide! P>
Un bon exemple est la catégorie Un bon résumé des raisons des objets immuables peut être trouvé ici p> code> classe: p>
Comme vous le savez déjà, c'est un excellent modèle pour multithreading. P>
Cela signifie aussi beaucoup Il existe quelques excellents exemples dans la bibliothèque de Core Java. Les sous-classes numériques sont un, mais je pense que le meilleur exemple est Pour la même raison, cela conduit également à Code plus lisible et maintenable fort>. Pas besoin de se soucier des autres utilisateurs de l'objet. P>
Ces deux raisons nous mènent à un autre motif important appelé chaîne code>. Vous les transmettez, concaténez-vous, obtenez des sous-chaînes, etc. et que vous n'avez jamais besoin de penser à d'autres endroits. S'il était mutable comme C / C ++ Char [] Code>, vous devez toujours garder cela à l'esprit. P>
Lorsque Java retourne par valeur (c.-à-d. Les références d'objet sont renvoyées à partir de méthodes), si, par exemple, je renvoie une chaîne comme suit: et la classe de cordes n'était pas immuable, puis le L'appelant de getString () code> pourrait modifier mystring code>, qui peut ne pas être le comportement souhaité; D'autres parties du système peuvent ne pas vouloir ou s'attendre à mystring code> pour changer. Donc, l'appelant ne peut changer que l'objet que mystring code> pointe vers, pas mystring code> lui-même. P> p>
'Par valeur' est une référence? Je pensais qu'ils étaient le contraire l'un de l'autre?
Vous devez vous rappeler que dans l'exemple ci-dessus, MyString est en réalité une référence à un objet à chaîne, pas l'objet lui-même. Donc, retourner cela.MYSTRING revient, par la valeur, la référence à MyString.
Selon mes informations, les chaînes Java sont immuables, donc je ne pense pas que l'appelant puisse modifier l'objet privé original mystring. Quand il essaie de le modifier, une nouvelle chaîne Obj est créée.
@Vikram Bhat: Oui, c'était le point de ma réponse. Si les chaînes n'étaient pas immuables, l'appelant serait en mesure de modifier le mystring d'origine.
@Dunnie ok alors, désolé mal interprété
C'est un peu tautologique, mais le principal avantage des objets immuables est qu'ils ne peuvent pas changer em>. Lorsque les objets peuvent changer, vous devez penser à ce qui pourrait arriver avec eux. Vous devez penser à comment, quand et pourquoi vous voulez les changer. Vous devez penser à quel autre code de votre application pourraient avoir accès au même objet et ce qu'il pourrait changer sans que vous sachiez. Les objets immuables réduisent efficacement le nombre (et la granularité) des "parties mobiles", vous devez jongler dans votre système et faciliter votre vie. P>
L'immuabilité est importante dans les programmes multi-threads, car alors vous savez qu'un thread ne corrompre pas une valeur utilisée dans un autre fil. Mais il est également utile dans un programme à une seule-thread.
Voici un exemple simple: p> Vous voulez bien vouloir savoir, quelle valeur est transmise à la barre ()? P> Supposons que FOO () est une grande fonction complexe. Dans cet exemple, je sais pour un fait absolu que lorsque FOO complète, je suis toujours égal à 17, car un entier est immuable. Si cela n'était pas vrai, je devrais étudier foo à dire si cela pourrait être changé ou non. P> Voici un exemple légèrement plus complexe. Supposons que j'ai un objet qui ressemble à un entier, mais est mutable. Appelons cela mutableInteger. Ensuite, dis-je écrire ceci: p> voyez-vous le problème avec ce qui précède? InventéInventory et actuelInventory Point sur le même objet. Tous les ajouts et soustraits agissent vraiment sur la même valeur, pas deux valeurs différentes, alors lorsque nous arrivons au test, il sera toujours égal. Le code ci-dessus ne fonctionnerait jamais si les objets sont mutables. S'ils sont immuables, les ajouts et les soustraits devraient renvoyer un objet de résultat plutôt que de mettre à jour en place, et cela fonctionnerait. P> Il y a des années, j'ai utilisé un compilateur Fortran où les entiers étaient mutables. Nous avions une fonction qui a accepté plusieurs paramètres, l'un d'entre eux un entier. Dans certains cas rares, la fonction a mis à jour l'entier. Ensuite, un jour, quelqu'un a écrit un appel à cette fonction qui passe la constante "2" comme entier. La fonction a décidé de mettre à jour le paramètre, modifiant ainsi la "constante" 2 à 1! Tous les autres endroits du programme qui ont utilisé une constante 2 maintenant mystérieusement obtenu la valeur 1 à la place. Cela a pris beaucoup de temps pour déboguer. P> p>
Wow, je pensais que j'étais le seul à pouvoir m'en souvenir de la part de la préparation.
Cela serait donc plus clair s'il était indiqué que Java doit donc toujours passer par référence et ne pas copier. Donc, toutes les valeurs passées peuvent être modifiées à moins qu'ils ne soient immuables. Je pense que c'est PHP, cependant, qui passe tout en valeur pour enregistrer le temps et la mémoire de copie, tout comme Java, mais si l'objet est modifié, il est copié et la fonction / méthode ne modifie pas l'objet.
@Dennis Eh bien, il y a des moments où vous voulez pouvoir modifier un objet transmis. Par exemple, créez un objet de commande avec la liste des éléments commandés, puis transmettez-le à une fonction qui calcule la taxe de vente et remplit ceci dans l'objet de commande. Ce n'est pas tellement immuable = bon / mutable = mauvais, comme sachant ce que vous faites dans chaque cas. Il y a quelque chose à dire pour les langues qui vous obligent à dire si vous passez à titre de référence ou par valeur et vous permettez ainsi de décider explicitement.
L'avantage principal de Java est dans l'utilisation de fils. Cela peut ne pas avoir de sens pour vous jusqu'à ce que vous ayez une compréhension de base des threads. En outre, cela a plus de sens lorsque vous avez l'expérience de la programmation et des choses qui peuvent aller mal. ESP sur de grands projets complexes.
Il peut simplifier votre compréhension des interactions dans votre code, si vous savez qu'un objet a un état qui ne peut pas être changé de l'extérieur.