Reputation: 2122
I need to store one instance of objects for some classes. I'd like to create a generic map like this:
<T> Map<Class<T>, T> objects;
But it's not possible and
Map<Class<?>, ?> objects;
Is not what I want because I would like to avoid casts:
MyClass c = (MyClass)objects.get(MyClass.class);
Also, I'd like Java to forbid me to do this:
objects.put(MyClass.class, new MyClass2());
One solution is to create a custom map so I would have a generic parameter <T>
, but is there a solution without creating a new class?
Upvotes: 1
Views: 1034
Reputation: 2153
If you can, instead of using the map directly, put in these methods to access the map always. That way you put the casting into the method and you dont see it anywhere else.
private Map<Class<?>, Object> map = new HashMap<Class<?>, Object>();
private <T> T getMapValue(Class<T> key){
return (T) map.get(key);
}
private <T> void putMapValue(Class<T> key, T value){
map.put(key, value);
}
And also it will forbid you from doing
putMapValue(MyClass.class, new MyClass2());
Upvotes: 0
Reputation: 100319
The standard Map
interface is not suitable for such scenario. However you can implement your own class which parameterizes get
and put
methods delegating them to the private Map
field:
public class ClassObjectMap {
private Map<Class<?>, Object> map = new HashMap<>();
public <T> void put(Class<T> clazz, T value) {
assert clazz.isInstance(value);
map.put(clazz, value);
}
public <T> T get(Class<T> clazz) {
return clazz.cast(map.get(clazz));
}
}
Adding other methods like remove()
or size()
is not very hard as well.
Upvotes: 3