Sembra che abbia un equivoco sulla differenza tra <Foo>
e <? extends Foo>
. Dalla mia comprensione, se avessimo
ArrayList<Foo> foos = new ArrayList<>();
Questo indica che oggetti di tipo Foo
possono essere aggiunti a questo elenco di array. Poiché le sottoclassi di Foo
sono anche di tipo Foo
, possono anche essere aggiunte senza errori, come illustrato da
ArrayList<Foo> foos = new ArrayList<>();
foos.add(new Foo());
foos.add(new Bar());
dove Bar extends Foo
.
Ora, dire che avevo definito foos
come
ArrayList<? extends Foo> foos = new ArrayList<>();
La mia attuale comprensione è che questo esprime some unknown type that extends Foo
. Prendo questo per significare che qualsiasi oggetto che sia una sottoclasse di Foo
può essere aggiunto a questa lista; il che significa che non vi è alcuna differenza tra ArrayList<Foo>
e ArrayList<? extends Foo>
.
Per testare questo, ho provato a scrivere il seguente codice
ArrayList<? extends Foo> subFoos = new ArrayList<>();
subFoos.add(new Foo());
subFoos.add(new Bar());
ma è stato richiesto con il seguente errore di compilazione
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)
Sulla base delle mie attuali conoscenze, posso capire perché potrei non essere in grado di aggiungere un Foo
a un elenco di <? extends Foo>
, perché non è una sottoclasse di se stesso; ma sono curioso di sapere perché non riesco ad aggiungere un Bar
alla lista.
Dove è il buco nella mia comprensione?