Кажется, у меня неправильное понимание разницы между <Foo>и <? extends Foo>. Из моего понимания, если бы мы имели
ArrayList<Foo> foos = new ArrayList<>();
Это указывает на то, что объекты этого типа Fooмогут быть добавлены в этот список массивов. Поскольку подклассы Fooтакже имеют тип 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)
Исходя из моего нынешнего понимания, я понимаю, почему я не могу добавить a Fooв список <? extends Foo>, потому что он не является подклассом сам по себе; но мне любопытно, почему я не могу добавить Barв список.
Где дыра в моем понимании?
<? extends Foo>является конкретным и неизвестным классом, который расширяется Foo. Операция с этим классом допустима только в том случае, если она допустима для любого подкласса Foo.