4

我有一个私有实例

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?
4

2 回答 2

5

不,一个简单java.util.Map的不支持这个。它是静态类型的,您所要求的基本上是基于另一个参数的运行时类型的一个参数的动态类型。

但是,GuavaClassToInstanceMap完全实现了您想要的:

一个映射,它的每个条目都将一个 Java 原始类型映射到该类型的一个实例。除了实现之外Map,还有其他类型安全的操作putInstance(java.lang.Class<T>, T)getInstance(java.lang.Class<T>)可用。

于 2013-04-16T13:08:35.063 回答
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

这样,您不必为 User 和 Role 创建特殊方法,并且仍然具有不为错误类型添加错误对象的安全性。

于 2013-04-16T13:22:23.827 回答