 |
Collections.unmodifiableX()
Posted by simongbrown on February 17, 2005 at 06:09 AM | Comments (6)
I just got bitten by the collections framework. I always thought that the Collections.unmodifiableX() methods returned an unmodifiable copy of the supplied collection, like a shallow copy. This is useful for getter methods where you want to return a copy of a collection to a client class so they can't directly alter the contents of that collection. This enforces encapsulation and ensures that clients use the methods that you have specified to manipulate your data.
But the Collections.unmodifiableX() methods don't work like that. Instead, they present an unmodifiable view of the specified collection. If you modify the underlying collection, this shows up in the unmodifiable view too. I won't be making that mistake again. To make a shallow copy of a collection, you can either use the clone() methods on the collection implementation classes or construct a new list/set/map, passing the original collection as an argument to the constructor.
It pays to read the javadocs, but without a unit test I would have spent even longer hunting this problem down.
Bookmark blog post: del.icio.us Digg DZone Furl Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment
-
Collections.checkedX, Collections.synchronizedX, Arrays.asList, Map.entrySet, Map.keySet and Map.values also work the same.
I guess if the copy is too expensive you could keep a reference to the unmodifiable view, clearing on writes to the underlying collection. Or even write a view subtype of the collection concerned that does the bookkeeping. No doubt, someone will point an Open Source version. Not covered by Jakarta Commons Collections as far as I can see.
Posted by: tackline on February 17, 2005 at 03:12 PM
-
For extra protection I always call the method twice:� � List safe = Collections.unmodifiableList(myList);� � List extraSafe = Collections.unmodifiableList(safe);
Posted by: jessewilson on February 18, 2005 at 08:12 AM
-
I fail to see how calling the method a second time would do anything. If it didn't work the first time, it won't work the second time; it still points to the same objects under the hood.
Posted by: afishionado on February 18, 2005 at 02:00 PM
-
I think Jesse was kidding...
Collections.getReadOnlyView() and Collections.getSynchronizedView() might have been better names...
Posted by: mgrev on February 19, 2005 at 10:45 PM
-
good joke, Jess )
As for the article,
I always thought that ...
WHY DID YOU THINK SO ????? READ SOURCES instead of starting such blogs
Posted by: _forest_ on February 21, 2005 at 12:10 AM
-
Collections.getReadOnlyView() ... yes, that would have been a much better name! Alternatively adding a getReadOnlyView() method to the Collection interface may have been a good idea.
Posted by: simongbrown on February 25, 2005 at 03:56 AM
|