3

我是 Java 新手。有人能告诉我这条线是什么意思吗?

class_A
...
Iterable< ? extends iface_classB> getThings();

iface_classB 在这里可以是 classB 的接口/抽象。

当我写如下内容时出现错误:

class_A myA = new classA()

Iterable< impl_of_iface_classB > anIterator = myA.getThings()

我想知道模板内的问号。我的猜测是它应该是任何派生的东西,iface_classB但似乎我错了。

非常感谢您的任何回答。

4

2 回答 2

4

您所做的假设与实际情况相反:

Iterable<? extends iface_classB> getThings();

意味着getThings()返回至少具有iface_classB. 因此,您不能将结果分配getThings()给 any Iterable< impl_of_iface_classB >,因为您只能确定对象公开了 a 的功能iface_classB

例如,如果返回的对象getThings()实际上是一个Iterable<impl2_of_iface_classB>,在哪里impl2_of_iface_classB扩展iface_classB?可迭代对象不具备impl_of_iface_classB对象的功能。

在实践中,如果B1B2派生自B,则完全允许有

A<? extends B> x; 
A<B1> y;
A<B2> z;

x = y;
x = z;

因此getThings()不能依赖泛型参数所代表的含义:它只能作为“普通”使用iface_classB

更重要的是,您希望能够分配给Iterable<iface_classB>,但您不能(除非您执行未经检查的强制转换,否则不会)。这是因为通配符本质上意味着“一组可行的通用参数”。想象一下,您将通配符替换为您使用的具体泛型参数:如果参数不匹配,由于类型不兼容,您会得到通常的编译时错误。编译器必须考虑所有情况,不允许您这样做。所以,

A<? extends B> x;
A<B> y = x;

虽然实际上是安全的,但不允许这样做,因为x可能会分配一个不同于 的参数B,从而为分配的两侧产生不同的类型。相反,

A<B> x;
A<? extends B> y = x;

是允许的,因为 的类型y代表一组备选方案,并且该组包括A<B>. 一旦y像上面这样分配,集合的具体估值就被实际选择了。

于 2012-06-04T08:32:37.803 回答
3

这是泛型的一部分,它与通配符有关 检查此链接http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html

于 2012-06-04T08:26:22.363 回答