After reviewing all the reviews, I came to the conclusion that no matter what I do, the solution will be some form of kludge (have a faint smell). I think this is due to the fact that the part of the collection API that creates non-modifiable instances does not provide for the exclusion of attachments of unmodifiable instances and does not provide a βpublicβ way for the client to correctly avoid nesting.
And due to considerations related to multiple class loaders and serialization via RMI, the only solution I really liked (Jorn Horstmann's comparative class comparison) has problems. However, when I take his approach and combine it with a modification of the approach to the class name (on the recommendation of Evgeny Kuleshov), I think that I get as close as possible to a solution that will help me in my multi-threaded distributed processing environment. And this is a bit like this:
public class MyCollections { private static final String UNMODIFIABLE_MAP_CLASS_NAME = Collections.unmodifiableMap(new HashMap()).getClass().getName(); public static <K, V> Map<K, V> unmodifiableMap(Map<K, V> map) { return map.getClass().getName().equals(UNMODIFIABLE_MAP_CLASS_NAME) ? map : Collections.unmodifiableMap(map); } }
This will still have all the advantages of link comparison, assuming everything happens in the same ClassLoader context, and the class string has been interned correctly. And he does this by politely preserving encapsulation (avoiding my code referencing directly to the class name). However, if these two assumptions are not fulfilled, then the evaluation will return to the standard string mapping, which will work if the class name does not change between different versions of the library (which, apparently, has a rather low probability).
Is there something that I forget or donβt see in this approach?
And thanks again, everyone, for your feedback. I really appreciate that.
source share