Pourquoi peut-on changer le inmodifiable liste si nous avons l'original?
En regardant le code de Collections
classe, j'ai appris que lorsque nous sommes à l'aide de la méthode unmodifiableList(List list)
ou unmodifiableCollection(Collection c)
il n'est pas de la création d'un nouvel objet, mais il est de retour à la référence de l'objet même et en remplaçant les méthodes qui peuvent modifier l'List
[ add
, addall
, remove
, retainAll
... ]
Alors, j'ai couru ce test:
List modifiableList = new ArrayList();
modifiableList.add ( 1 );
List unmodifiableList = Collections.unmodifiableList( modifiableList );
//unmodifiableList.add(3); //it will throw the exception
modifiableList.add ( 2 );
System.out.println( unmodifiableList );
résultat est [ 1,2 ]
.
Maintenant, le point est pourquoi il est fait référence au même objet? Pourquoi ne pas créer un nouvel objet?
- Ce que vous cherchez s'appelle une "liste immuable." La goyave a cette. (guava-libraries.googlecode.com)
- Google Goyave, ImmutableCollections <-- mise à Jour du lien de la doc.
Vous devez vous connecter pour publier un commentaire.
(réponse de la question d'en bas)
Lorsque vous créez un inmodifiable liste, le but est qu'il ne doit pas être modifié par d'autres personnes que vous - à-d. les clients d'un API.
la méthode
unmodifiableList(..)
crée un nouvel objet de typeUnmodifiableList
(mais ce n'est pas une classe publique), qui obtient la liste d'origine, et les délégués de toutes les méthodes sauf les moyens de le modifier.Le point est, comme indiqué dans la documentation:
Donc, un exemple: Vous avez un
List
de périphériques que votre API a détecté et peut fonctionner, et que vous souhaitez leur donner un client de votre API. Mais il n'est pas censé changement eux. Donc, vous avez deux options:List
, de sorte que même si il le modifie, cela ne change pas votre listeEt maintenant voici la réponse pour le titre de votre question - la inmodifiable liste est une vue de la collection d'origine. Donc, si vous avez besoin d'ajouter un nouvel élément pour il - dire, vous avez découvert un nouveau dispositif qui vient d'être branchés, les clients seront en mesure de voir dans leur inmodifiable vue.
Performance. Il n'a tout simplement pas d'échelle pour faire une copie complète. Il serait temps linéaire de l'opération pour faire une copie complète qui, évidemment, n'est pas pratique. Aussi, comme d'autres l'a déjà noté, le point est que vous pouvez passer la référence de la inmodifiable liste autour de vous sans avoir à vous inquiéter qu'il est changé. Ceci est très utile pour les programmes multithread.
À partir de la documentation:
Je crois que le secret réside dans les détails de mise en œuvre... de la Collection.unmodifiableList() tout simplement vous donner décorées de liste modifiable. Je veux dire inmodifiable liste contient des références à modifiables liste en interne.
La accepté de Répondre à par Bozho est correct. Voici un peu plus d'infos, un exemple de code, et une suggestion de solution de rechange.
La unmodifiableList Est Soutenue Par la Liste d'Origine
Que
unmodifiableList
méthode dansCollections
classe utilitaire ne pas créer une nouvelle liste, il crée un pseudo-liste soutenu par la liste d'origine. Tout ajouter ou supprimer des tentatives faites par le biais de la "inmodifiable" objet sera bloqué, donc le nom de la vie jusqu'à son but. Mais en effet, comme vous l'avez montré, la liste d'origine peut être modifié, et affecte à la fois notre second pas tout à fait inmodifiable liste.Cela est précisé dans la documentation de classe:
Que le quatrième mot est la clé:
view
. La nouvelle liste d'objet n'est pas une nouvelle liste. C'est une superposition. Tout comme papier calque ou la transparence du film sur un dessin ne vous empêche de faire des marques sur le dessin, il ne vous empêchera pas d'aller en dessous pour modifier le dessin d'origine.Morale de l'Histoire: Ne pas utiliser des Collections.unmodifiableList pour faire la défensive des copies des listes.
Idem pour
Collections.unmodifiableMap
,Collections.unmodifiableSet
, et ainsi de suite.Voici un autre exemple montrant la question.
Google Goyave
Au lieu de la
Collections
classe, pour une programmation défensive, je recommande d'utiliser le Google Goyave de la bibliothèque et de ses ImmutableCollections installation.Vous pouvez faire une nouvelle liste.
Ou vous pouvez faire une défensive copie d'une liste existante. Dans ce cas, vous obtiendrez une nouvelle liste séparée. La suppression de la liste d'origine seront pas affecter (réduire) la liste immuable.
Mais rappelez-vous, tandis que la collecte est propre définition est séparé, les objets contenus sont partagés par les deux à la liste d'origine et la nouvelle liste immuable. Lors de la prise de défensive exemplaire, nous ne sommes pas dupliquer le "chien" de l'objet. Un seul objet chien reste en mémoire, les deux listes contiennent une référence pointant vers le même chien. Si les propriétés dans le "chien" objet sont modifiées, les deux collections sont pointant vers cette même objet chien et donc les deux collections de voir le chien douce de la valeur de la propriété.
J'ai Trouvé une façon de le faire est
vous devriez aller pour la création de nouveaux Objet d'une liste, uniquement lorsque l'Objet original va être changé et vous avez besoin d'une copie de sauvegarde , lorsque quelqu'un corrompt-il , u peut le remplacer par un nouvel Objet.
Pour créer un ummodifiable objet, je vais envelopper l'objet d'origine et éviter d'ajouter ,de supprimer en jetant exception. mais tu sais ,je peux changer chaque objet présent dans la liste .comme si u ont un objet personne dans un umodifiable liste , je peux encore changer le nom de la personne objet de la liste.