我有一个私人实例
private final Map<Class<?>, ?> map;
从语法上讲,这是正确的。我想做的就是这个。
public class User {
}
public class UserSubclass extends User {
}
public class Role {
}
map.put(User.class, new User()); // valid
map.put(User.class, new UserSubclass()); // valid
map.put(Role.class, new Role()); // valid
// But when I do the following I need to get an error
map.put(User.class, new Role(); // invalid, compiler error
答案 0 :(得分:5)
不,简单java.util.Map
不支持此功能。它是静态类型,你要求的基本上是基于另一个参数的运行时类型动态输入一个参数。
但是,Guava类ClassToInstanceMap
完全符合您的要求:
一个映射,其每个条目将Java原始类型映射到该类型的实例。除了实施
Map
之外,还可以使用其他类型安全操作putInstance(java.lang.Class<T>, T)
和getInstance(java.lang.Class<T>)
。
答案 1 :(得分:4)
默认情况下,您无法执行此操作,但您可以执行的操作是创建自己的通用安全地图,这将起作用。
GenericMap看起来像这样:
class GenericMap extends HashMap<Class<?>, Object> {
public <T> T putClassAndInstance(Class<T> c, T o){
return c.cast(super.put(c, o));
}
public <T> T getInstance(Class<T> c) {
return c.cast(super.get(c));
}
}
然后可以像:
一样使用GenericMap map = new GenericMap();
map.putClassAndInstance(User.class, new User()); // valid
map.putClassAndInstance(User.class, new UserSubclass()); // valid
map.putClassAndInstance(Role.class, new Role()); // valid
map.putClassAndInstance(User.class, new Role()); // invalid, compiler error
这样,您就不必为用户和角色创建特殊方法,并且仍然可以安全地为错误的类型添加错误的对象。