Mi sembra di avere un malinteso sulla differenza tra <Foo>e <? extends Foo>. Dalla mia comprensione, se avessimo
ArrayList<Foo> foos = new ArrayList<>();
Ciò indica che è Foopossibile aggiungere oggetti di tipo a questo elenco di array. Poiché anche le sottoclassi di Foosono 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 fooscome
ArrayList<? extends Foo> foos = new ArrayList<>();
La mia attuale comprensione è che ciò esprime some unknown type that extends Foo. Presumo che ciò significhi che qualsiasi oggetto che è una sottoclasse di Foopuò essere aggiunto a questo elenco; significa che non c'è differenza tra ArrayList<Foo>eArrayList<? extends Foo> .
Per provare 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 della mia attuale comprensione, posso capire perché potrei non essere in grado di aggiungere un Fooa un elenco di <? extends Foo>, perché non è una sottoclasse di se stesso; ma sono curioso di sapere perché non riesco ad aggiungere aBar alla lista.
Dov'è il buco nella mia comprensione?
<? extends Foo>è una classe specifica e sconosciuta che si estende Foo. Un'operazione con questa classe è legale solo se sarebbe legale per qualsiasi sottoclasse di Foo.