5

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>>

我想知道,发生了什么?

也许编译器无法检测到扩展类是泛型类型的一部分。

4

2 回答 2

2

您将需要使用以下内容:

Map<String, ? extends GenericClass<? extends Serializable>> map2 =
        new HashMap<String, GenericClass<String>>();

嵌套通配符与顶级通配符有很大不同——只有后者执行通配符捕获。因此,HashMap<String, GenericClass<String>>被认为不可转换为Map<String, GenericClass<? extends Serializable>>,因为GenericClass<? extends Serializable>它是一个具体的类型参数(并且因为泛型不是协变的)。

有关嵌套通配符的更多信息,请参阅这篇文章:泛型方法上的多个通配符使 Java 编译器(和我!)非常困惑

于 2013-07-18T14:32:30.943 回答
1
Map<String,? extends Serializable> map1 = new HashMap<String,String>();

map1包含一个只需要一个未知数的无界 。因此,它找不到将 this 绑定到的通用对象,除了.VSerializablenull

Map<String,GenericClass<? extends Serializable>> map2 = new HashMap<String, GenericClass<String>>();

由类型(在本例中)和( map2)限定。这就是 Java 编译器看到边界的方式。KStringVClass<? exends Serializable

从本质上讲,除了你只会看到的 null 之外,你不能做put任何事情。鉴于,将基本上“渲染”为.map1map1.put(String key, null value) //Compiler is asking WTF heremap2map2.put(String key, Class<? extends Serializable> value); //Much better...

由于 in 的约束Vmap2其声明中的签名必须相同。

于 2013-07-18T12:21:28.807 回答