我在很多场合注意到了生产java代码,
的用法Collection< ? extends foo> var
我的问题不是
Collection<foo> var
意思是一样的。一个与另一个的语义差异是什么?
谢谢!
答案 0 :(得分:1)
由于Collection<? extends Foo>
与Collection<SubClassOfFoo>
匹配,而Collection<Foo>
则不匹配。
简单地说,如果是SubClass extends Foo
,那么Collection<SubClass> extends Collection<Foo>
就不行了,所以你需要使用通配符来表示你允许子类集合。
答案 1 :(得分:1)
假设我们有一个方法
void foo(List<Parent> bar)
我们希望传递它List<Child>
,遗憾的是我们不能。如果Foo
是Bar
的子类型,那么通用容器不是“协变的”,那么List<Foo>
不是List<Bar>
的子类型,它们是不变的。要解决这个问题,我们使用通配符。
如果我们宣布我们的方法
void foo(List<? extends Parent> bar)
现在我们可以传递List<Child>
或List<Parent>
。使用extends
的通配符可以为我们提供协方差。
双重地,如果我们要传递Child
是子类型的对象列表,那么我们可以做
void foo(List<? super Child>)
并传递List<Parent>
。这是“逆变”,就像协方差一样但是失败了。
这是一个有点令人困惑的话题,但方差的要点是允许集合具有与其参数相同的子类型和超类型。
答案 2 :(得分:0)
Collection<foo> var
表示它仅包含foo
及其子类。 Collection< ? extends foo> var
表示它只能包含foo
的一个特定子类及其子类。这是完全不同的。