Un objet est considéré comme immuable si son état ne peut pas changer après sa construction. Une fois que vous avez créé une instance immuable d'une collection, elle contient les mêmes données tant qu'une référence à cette collection existe.
L'un des avantages d'une collection immuable est qu'elle est automatiquement thread safe. Les collections contenant des objets immuables sont automatiquement thread safe après leur construction. Après avoir créé une telle collection, vous pouvez la confier à plusieurs threads, et ils verront tous une vue cohérente.
Cependant, une collection immuable d'objets n'est pas la même chose qu'une collection d'objets immuables. Si les éléments contenus sont mutables, la collection peut se comporter de manière incohérente ou donner l'impression que son contenu change.
En d'autres termes, si vous ajoutez un peu d'immuabilité à quelque chose de mutable, vous obtenez la mutabilité. Et si vous ajoutez un peu de mutabilité à quelque chose d'immuable, vous obtenez la mutabilité.
Immuable et non modifiable ne sont pas identiques :
Les collections immuables se comportent de la même manière que les wrappers Collections.unmodifiable.... Cependant, ces collections ne sont pas des wrappers - ce sont des structures de données implémentées par des classes où toute tentative de modification des données entraîne la levée d'une exception.
Si vous créez une liste et la passez à la méthode Collections.unmodifiableList, vous obtenez une vue non modifiable. La liste sous-jacente est toujours modifiable, et les modifications apportées sont visibles à travers la liste renvoyée, donc elle n'est pas réellement immuable.
Pour démontrer ce comportement, créez une liste et passez-la à Collections.unmodifiableList. Si vous essayez d'ajouter directement à cette liste non modifiable, une UnsupportedOperationException est levée.
Mais, si vous modifiez la liste originale, aucune erreur n'est générée, et la liste non modifiable a été modifiée.
Dans ce cas, pour rendre une collection immuable une fois qu'elle a été construite, c'est une bonne pratique de ne pas maintenir une référence à la collection de support. Cela garantit absolument l'immuabilité.
En outre, pour permettre à certains clients d'accéder en lecture seule à vos structures de données. Vous pouvez conserver une référence à la collection de sauvegarde mais distribuer une référence au wrapper. De cette façon, les clients peuvent regarder mais ne peuvent pas modifier, tandis que vous conservez un accès complet.
Ainsi, une collection immuable peut contenir des objets mutables, et si c'est le cas, la collection n'est ni immuable ni thread safe.