我可以在地图中使用通配符,例如Map <class <?>,?&gt; </class <?>

时间:2013-04-16 13:07:14

标签: java generics

我有一个私人实例

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
  1. 我应该如何申报地图?
  2. 如何将HashMap的对象实例化为此Map?

2 个答案:

答案 0 :(得分:5)

不,简单java.util.Map不支持此功能。它是静态类型,你要求的基本上是基于另一个参数的运行时类型动态输入一个参数。

但是,GuavaClassToInstanceMap完全符合您的要求:

  

一个映射,其每个条目将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

这样,您就不必为用户和角色创建特殊方法,并且仍然可以安全地为错误的类型添加错误的对象。