Parece que tenho um mal-entendido sobre a diferença entre <Foo>
e <? extends Foo>
. Pelo meu entendimento, se tivéssemos
ArrayList<Foo> foos = new ArrayList<>();
Isso indica que objetos do tipo Foo
podem ser adicionados a essa lista de matrizes. Como as subclasses de Foo
também são do tipo Foo
, elas também podem ser adicionadas sem erro, conforme ilustrado por
ArrayList<Foo> foos = new ArrayList<>();
foos.add(new Foo());
foos.add(new Bar());
onde Bar extends Foo
.
Agora, digamos que eu tenha definido foos
como
ArrayList<? extends Foo> foos = new ArrayList<>();
Meu entendimento atual é que isso se expressa some unknown type that extends Foo
. Entendo que isso significa que quaisquer objetos que são uma subclasse de Foo
podem ser adicionados a esta lista; significando que não há diferença entre ArrayList<Foo>
e ArrayList<? extends Foo>
.
Para testar isso, tentei escrever o seguinte código
ArrayList<? extends Foo> subFoos = new ArrayList<>();
subFoos.add(new Foo());
subFoos.add(new Bar());
mas foi solicitado o seguinte erro de compilação
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)
Com base no meu entendimento atual, posso ver por que não consigo adicionar a Foo
a uma lista de <? extends Foo>
, porque ela não é uma subclasse; mas estou curioso para saber por que não consigo adicionar um Bar
à lista.
Onde está o buraco no meu entendimento?
<? extends Foo>
é uma classe específica e desconhecida que se estende Foo
. Uma operação com esta classe é legal apenas se for legal para qualquer subclasse de Foo
.