我有一个由两个类实现的接口(interface)
interface I {}
class A implements I {}
class B implements I {}
现在我想创建一个映射,它可以将键作为使用 I
实现的任何对象的类,并将值作为该类的对象。这样我就可以做到这一点:
map.put(A.class, new A());
map.put(B.class, new B());
以下所有情况都应该给出错误:
map.put(A.class, new B());
map.put(I.class, new B());
以下 map
这样无效:
Map<Class<? extends I>, ? extends I> map;
因为第一次捕获与第二次捕获不同。如何获得所需的 map ?
最佳答案
怎么样
interface I {
}
class A implements I {
}
class B implements I {
}
public class Example {
public static <T extends I, M extends Map<Class<T>, T>> void put(M map, Class<T> key, T value) {
map.put(key, value);
}
public static void main(String[] args) {
Map map = new HashMap<Class<I>, I>();
put(map, A.class, new A());
put(map, A.class, new B()); // error
put(map, B.class, new A()); // error
put(map, B.class, new B());
}
}
如果您不介意在运行时出现错误,您可以这样做:
interface I {
}
class A implements I {
}
class B implements I {
}
public class MyMap implements Map<Class<? extends I>, I> {
private final Map<Class<? extends I>, I> map;
public MyMap(Map<Class<? extends I>, I> map) {
this.map = map;
}
public int size() {
return map.size();
}
public boolean isEmpty() {
return map.isEmpty();
}
public boolean containsKey(Object key) {
return map.containsKey(key);
}
public boolean containsValue(Object value) {
return map.containsValue(value);
}
public I get(Object key) {
return map.get(key);
}
public I put(Class<? extends I> key, I value) {
assert key.getClass().isAssignableFrom(value.getClass());
return map.put(key, value);
}
public I remove(Object key) {
return map.remove(key);
}
public void putAll(Map<? extends Class<? extends I>, ? extends I> m) {
map.putAll(m);
}
public void clear() {
map.clear();
}
public Set<Class<? extends I>> keySet() {
return map.keySet();
}
public Collection<I> values() {
return map.values();
}
public Set<Entry<Class<? extends I>, I>> entrySet() {
return map.entrySet();
}
public static void main(String[] args) {
MyMap map = new MyMap(new HashMap<Class<? extends I>, I>());
map.put(A.class, new A());
map.put(A.class, new B()); // runtime error
map.put(B.class, new A()); // runtime error
map.put(B.class, new B());
}
}
如果 map
实现 Map
,就不可能出现这样的编译时错误:
put(map, A.class, new A());
put(map, A.class, new B()); // error
put(map, B.class, new A()); // error
put(map, B.class, new B());
这是因为无法使用 Map
接口(interface)将 V
指定为依赖于 K
。您必须向客户提供一个具有运行时错误并实现 Map 的类,或者一个具有编译时错误且未实现 Map 的类。
关于java - 使用相同的参数类型创建通用映射来保存类型的键和值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33008550/