Java通过<? extends class>
为我提供了一种过滤可用于的java类的方法
在这种情况下构建新的HashMap,例如:
我可以这样做:
Map<String,? extends Serializable> map1 = new HashMap<String,String>();
这是正确的,因为String实现了Serializable,所以编译器允许我这样做。
但是当我尝试这样做时:
Map<String,GenericClass<? extends Serializable>> map2 = new HashMap<String, GenericClass<String>>();
成为GenericClass:
public class GenericClass<T>
{
.
.
.
}
编译器抛出错误说:
Type mismatch: cannot convert from HashMap<String,GenericClass<String>> to Map<String,GenericClass<? extends Serializable>>
我想知道,会发生什么?
也许编译器无法检测extends类是泛型类型的一部分。
答案 0 :(得分:2)
您需要使用以下内容:
Map<String, ? extends GenericClass<? extends Serializable>> map2 =
new HashMap<String, GenericClass<String>>();
嵌套通配符与顶级通配符有很大不同 - 只有后者执行wildcard capture。因此,HashMap<String, GenericClass<String>>
被视为Map<String, GenericClass<? extends Serializable>>
无法转换,因为GenericClass<? extends Serializable>
是具体类型参数(并且因为泛型aren't covariant)。
有关嵌套通配符的更多信息,请参阅此帖子:Multiple wildcards on a generic methods makes Java compiler (and me!) very confused
答案 1 :(得分:1)
Map<String,? extends Serializable> map1 = new HashMap<String,String>();
map1
包含无界 V
,只需要Serializable
的未知数。因此除了null
之外,它无法找到将其绑定到的通用对象。
Map<String,GenericClass<? extends Serializable>> map2 = new HashMap<String, GenericClass<String>>();
map2
有界类型K
(在本例中为String
)和V
(Class<? exends Serializable
)。这就是Java编译器看到边界的方式。
从本质上讲,put
除了null之外,你不能map1
,因为你只会看到map1.put(String key, null value) //Compiler is asking WTF here
。
然而,map2
将基本上“呈现”为map2.put(String key, Class<? extends Serializable> value); //Much better...
。
由于V
中的绑定map2
,签名在声明中必须相同。