我有两张地图Something1
和Something2
。两者都扩展了类Something
。
Map<Class<? extends Something1>, String> m1
Map<Class<? extends Something2> ,String> m2
我想创建一个更通用的地图m3
,我可以像这样分配m1
或m2
:
Map<Class<? extends Something>, String> m3 = m1;
但是我得到以下例外:
Type mismatch: cannot convert from Map<Class<? extends Something1>, String> to Map<Class<? extends Something>, String>
我也尝试使用Class<?>
,但它似乎无法正常工作。
我做错了什么?
答案 0 :(得分:2)
这是不可能的。请考虑以下事项:
Map<Class<? extends Something1>, String> m1 = new HashMap<>();
m1.put(Something1.class, "Something1"); // OK
m1.put(Something2.class, "Something2"); // Error
因此,您无法将Something2
作为密钥。
相反:
Map<Class<? extends Something2>, String> m2 = new HashMap<>();
m2.put(Something1.class, "Something1"); // Error
m2.put(Something2.class, "Something2"); // OK
在此,您无法将Something1
作为密钥。
但是,如果您创建一个使用基类作为通配符的版本,它就可以工作。看看这个:
Map<Class<? extends Something>, String> m = new HashMap<>();
m.put(Something1.class, "Something1"); // OK
m.put(Something2.class, "Something2"); // OK
您的问题是您正在尝试为通用类型分配更具体的类型。像这样:
m = m1; // Boom, but why?
为什么这不起作用。好吧,这是因为如果你允许这个任务,你就可以这样做:
m.put(Something2.class, "Something2");
从那以后你会把Something2
作为Something1
类型地图的关键字,显然不行。
答案 1 :(得分:0)
非通配符类型参数必须完全相同才能兼容。 Class<? extends Something1>
与Class<? extends Something>
不完全相同(即使其中一个是另一个的子类型),因此Map
的{{1}}与Map
的{{1}}不兼容另一个。
如果你想要一个可以接受具有不同类型参数的Map
的类型,你需要在顶层有一个通配符(但请注意,这将有效地使Map
只读):< / p>
Map<? extends Class<? extends Something>, String> m3 = m1;