我是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
得出的任何东西,但似乎我错了。
非常感谢您的回答。
答案 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
个对象的功能。
实际上,如果B1
和B2
来自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