I have a class with a collection of Wildcard Types that is a singleton, something like:
public ObliviousClass{
private static final ObliviousClass INSTANCE = new ObliviousClass();
private Map<Key, Type<?>> map = new HashMap<Key, Type<?>>();
public void putType(Key key, Type<?> type){
map.put(type);
}
// returns the singleton
public static ObliviousClass getInstance(){
return INSTANCE;
}
}
I’d like to be able to add different Parameterized types to this collection in client code:
void clientMethod(){
ObliviousClass oc = ObliviousClass.getInstance();
Type<Integer> intType = ...
Type<String> stringType = ...
oc.putType(new Key(0), intType);
oc.putType(new Key(1), stringType);
}
Up to this point, as I understand it, everything is ok. But a client also needs to be able to get a Type<?> provided the Key. So a method something like the following would be added to ObliviousClass:
public Type<?> getType(Key key){
return map.get(key);
}
But in my handy copy of Effective Java, I read:
Do not use wildcard types as return types.
I understand the issue, as the client would have to cast the returned Type<?>. But I really do not want to make ObliviousClass a generic type, ObliviousClass<T>, because then my client code above would not work…
Is there a better design for what I am trying to do?
-My current solution is to provide a static method for the client; something along the lines of:
public static <T> void getType(ObliviousClass instance, Key key, Type<T> dest){
dest = (Type<T>)instance.getType(key);
}
I searched around, but wasn’t able to find an answer that totally cleared my confusion.
Here’s a type-safe way to store multiple instances of a given type in a map. The key is that you need to provide a
Classinstance when retrieving values in order to perform runtime type-checking, because static type information has been erased.Usage would look like this: