可迭代< ?扩展iface_class>

时间:2012-06-04 08:23:36

标签: java

我是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得出的任何东西,但似乎我错了。

非常感谢您的回答。

2 个答案:

答案 0 :(得分:4)

你做出的假设与真正的假设相反:

Iterable<? extends iface_classB> getThings();

表示getThings()返回具有至少 iface_classB功能的对象的可迭代对象。因此,您无法将getThings()的结果分配给任何Iterable< impl_of_iface_classB >,因为您只能确保对象公开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,就会实际选择集合的具体估值。

答案 1 :(得分:3)

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