Reputation: 323
What I would like to have is something like this:
public abstract Class Content {
private Map<Class<? extends Content>, List<? extends Content>> relations;
}
Content has a bunch of subclasses - A,B,C,D etc...
The most frequent use case is to get all A's:
public List<A> getA() {
return (List<A>)relations.get(A.class);
}
Kind of ok - apart from the ugly cast.
But the real problem is there's nothing stopping me from doing something stupid like:
relations.put(A.class, List<B> myListOfBs);
So a call to getA() above would result in a horrible cast exception. Is there any way I can write it so the compiler would warn me in the above example - and also remove the need for the ugly cast.
Thanks
Upvotes: 3
Views: 193
Reputation: 424983
Create a custom Map
interface that fixes the type to the same type:
interface RelatedMap<T> extends Map<Class<T>, List<T>> {}
then
private RelatedMap<? extends Content> relations;
Upvotes: 0
Reputation: 81074
You can create a wrapper around a Map
and use a generic method to constrain your put method:
public class HeterogeneousContainer {
private final Map<Class<? extends Content>, List<? extends Content>> map;
public <T extends Content> void put(Class<T> type, List<T> values) {
map.put(type, values);
}
public <T extends Content> List<T> get(Class<T> type) {
//this warning can be safely suppressed after inspection
return (List<T>) map.get(type);
}
}
Now you know that as long as the users of the container aren't using it improperly (i.e. in raw form) then the key and value must correspond...you couldn't call put(B.class, listOfAs);
.
Upvotes: 3