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 è Foo
possibile aggiungere oggetti di tipo a questo elenco di array. Poiché anche le sottoclassi di Foo
sono 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 ciò esprime some unknown type that extends Foo
. Presumo che ciò significhi che qualsiasi oggetto che è una sottoclasse di Foo
può 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 Foo
a 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
.