声明Map <string,class <? extends =“”serializable =“”>&gt; </string,class <?>

时间:2013-07-18 12:16:57

标签: java generics hashmap extends serializable

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类是泛型类型的一部分。

2 个答案:

答案 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)和VClass<? 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,签名在声明中必须相同。