I'm currently refreshing my Java knowledge with an mid-sized coding example. I have a data structure Map<String, String>
, and initialize it typically with new LinkedHashMap<>()
to preserve insertion order. I use this very often in my code, and I want to get rid of the declaration repetition. In C++ I would alias the map, but in Java there is no alias, as far as I know.
So I came up with the idea to subclass the generic like this:
public class Attributes extends LinkedHashMap<String, String> {
public Attributes() {
super();
}
public Attributes(Map<? extends String, ? extends String> map) {
super(map);
}
}
This looks good so far, but now I want to create an unmodifiable copy of this, because attributes should be part of immutable/unmodifiable data structures. Before I used this:
Map<String, String> unmodifiableAttributes = Collections.unmodifiableMap(
new LinkedHashMap<>(attributes)
);
This doesn't work for a derived class, I tried this:
Attributes unmodifiableAttributes = Collections.unmodifiableMap(
new Attributes(attributes)
);
The compiler rejects it with Incompatible types
.
Is there an easy way to get an unmodifiable (or immutable) copy of such a subclass? Or is my idea completely wrong? I don't want to write a full featured decorator, just a few lines of code.
UPDATE
So far, it looks like there is no good solution for what I want to do. I looked at the source code of the Java Collections class, and there are internal classes for unmodifiable maps and similar collections. These are used to wrap the input collection and are returned by the correcponding static methods. One could reimplement this, but I think would be too much overhead.
We had more discussion about LSP violation instead of the original question, which is indeed an interesting question too.