Wydaje mi się, że mam nieporozumienie na temat różnicy między <Foo>i <? extends Foo>. Z mojego zrozumienia, gdybyśmy mieli
ArrayList<Foo> foos = new ArrayList<>();
Oznacza to, że Foodo tej listy tablic można dodać obiekty typu . Ponieważ podklasy Foosą również typu Foo, można je również dodawać bezbłędnie, jak pokazano za pomocą
ArrayList<Foo> foos = new ArrayList<>();
foos.add(new Foo());
foos.add(new Bar());
gdzie Bar extends Foo.
Powiedzmy, że zdefiniowałem foosjako
ArrayList<? extends Foo> foos = new ArrayList<>();
Moje obecne rozumienie jest takie, że to wyraża some unknown type that extends Foo. Rozumiem, że oznacza to, że wszelkie obiekty, które są podklasą, Foomożna dodać do tej listy; co oznacza, że nie ma różnicy między ArrayList<Foo>i ArrayList<? extends Foo>.
Aby to przetestować, próbowałem napisać następujący kod
ArrayList<? extends Foo> subFoos = new ArrayList<>();
subFoos.add(new Foo());
subFoos.add(new Bar());
ale został wyświetlony monit o następujący błąd kompilacji
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)
W oparciu o moje obecne rozumienie rozumiem, dlaczego mogę nie być w stanie dodać Foolisty do listy <? extends Foo>, ponieważ nie jest ona sama w sobie podklasą; ale jestem ciekawy, dlaczego nie mogę dodać Barlisty do listy.
Gdzie jest dziura w moim rozumieniu?
<? extends Foo>jest specyficzną i nieznaną klasą, która się rozszerza Foo. Operacja z tą klasą jest legalna tylko wtedy, gdy byłaby legalna dla dowolnej podklasy Foo.