我似乎对<Foo>
和之间的区别有误解<? extends Foo>
。据我了解,如果我们有
ArrayList<Foo> foos = new ArrayList<>();
这表明Foo
可以将类型的对象添加到此数组列表中。由于的子类Foo
也是type Foo
,因此也可以添加它们而不会出现错误,如下所示
ArrayList<Foo> foos = new ArrayList<>();
foos.add(new Foo());
foos.add(new Bar());
在哪里Bar extends Foo
。
现在,说我定义foos
为
ArrayList<? extends Foo> foos = new ArrayList<>();
我目前的理解是,这表示some unknown type that extends Foo
。我的意思是可以将任何属于其子类的对象Foo
添加到此列表中。表示ArrayList<Foo>
和之间没有区别ArrayList<? extends Foo>
。
为了对此进行测试,我尝试编写以下代码
ArrayList<? extends Foo> subFoos = new ArrayList<>();
subFoos.add(new Foo());
subFoos.add(new Bar());
但系统提示以下编译错误
no suitable method found for add(Foo)
method java.util.Collection.add(capture#1 of ? extends Foo) is not applicable
(argument mismatch; Foo cannot be converted to capture#1 of ? extends Foo)
no suitable method found for add(Bar)
method java.util.Collection.add(capture#2 of ? extends Bar) is not applicable
(argument mismatch; Bar cannot be converted to capture#2 of ? extends Bar)
根据目前的理解,我可以理解为什么为什么我不能在Foo
的列表中添加<? extends Foo>
,因为它不是其自身的子类。但是我很好奇为什么我不能Bar
在列表中添加一个。
我的理解力在哪里?
3
PECS(生产者扩展,消费者超级)。
—
蚊蚋
<? extends Foo>
是一个特定的和未知的扩展类Foo
。此类的操作只有在的任何子类都合法的情况下才是合法的Foo
。
哇。您对Java的泛型了解得越多,发现的内容就越复杂。
—
梅森·惠勒