我有一个由两个类实现的接口
interface I {}
class A implements I {}
class B implements I {}
现在我想创建一个映射,该映射可以将key作为使用I
实现的任何对象的Class,并将value作为该Class的Object。所以我可以这样做:
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;
因为第一次捕获与第二次捕获不同。我怎样才能获得所需的地图?
答案 0 :(得分:1)
怎么样?
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());
这是因为无法使用V
接口将K
指定为依赖Map
。您将不得不为客户端提供具有运行时错误并实现Map的类,或者具有编译时错误的类,并且不实现Map。
答案 1 :(得分:0)
此代码是否解决了您的目的?
import java.util.*;
public class Test {
Map< Class<? extends I>, I> map = new HashMap < Class<? extends I>, I>();
public static void main(String args[]){
Test t = new Test();
t.addMaps();
}
private void addMap(I obj){
map.put(obj.getClass(),obj);
}
private void addMaps(){
addMap(new A());
addMap(new B());
System.out.println(map);
}
}
interface I {}
class A implements I {}
class B implements I {}
class C{};
答案 2 :(得分:-1)
ClassToInstanceMap
在Guava中完全符合您的要求,并且是类型安全的。