我注意到在生产 Java 代码的很多场合,使用
Collection< ? extends foo> var
我的问题是没有
Collection<foo> var
意思一样。一个与另一个的语义差异是什么?
谢谢!
我注意到在生产 Java 代码的很多场合,使用
Collection< ? extends foo> var
我的问题是没有
Collection<foo> var
意思一样。一个与另一个的语义差异是什么?
谢谢!
因为Collection<? extends Foo>
匹配Collection<SubClassOfFoo>
,whileCollection<Foo>
不匹配。
简单地说,如果SubClass extends Foo
,那么 就不是真的Collection<SubClass> extends Collection<Foo>
,所以你需要使用通配符来表示你允许子类的集合。
假设我们有一个方法
void foo(List<Parent> bar)
我们想通过它List<Child>
,不幸的是我们不能。Foo
如果是Bar
then的子类型,则通用容器不是“协变的”,它们List<Foo>
不是 的子类型List<Bar>
,它们是不变的。为了解决这个问题,我们使用通配符。
如果我们声明我们的方法
void foo(List<? extends Parent> bar)
现在我们可以传递它 aList<Child>
或 a List<Parent>
。通配符extends
给我们协方差。
双重的,如果我们想传递Child
一个子类型的对象列表,那么我们可以这样做
void foo(List<? super Child>)
并将其传递给List<Parent>
. 这是“逆变”,就像协方差一样,但失败了。
这是一个稍微令人困惑的话题,但变化的要点是允许集合具有与其参数相同的子类型和超类型。
Collection<foo> var
意味着它只包含foo
及其子类。Collection< ? extends foo> var
意味着它只能包含一个特定的子类foo
和子类。这是完全不同的。