Je semble avoir un malentendu sur la différence entre <Foo>et <? extends Foo>. D'après ma compréhension, si nous avions
ArrayList<Foo> foos = new ArrayList<>();
Cela indique que des objets de type Foopeuvent être ajoutés à cette liste de tableaux. Comme les sous-classes de Foosont également de type Foo, elles peuvent également être ajoutées sans erreur, comme illustré par
ArrayList<Foo> foos = new ArrayList<>();
foos.add(new Foo());
foos.add(new Bar());
où Bar extends Foo.
Maintenant, disons que j'avais défini fooscomme
ArrayList<? extends Foo> foos = new ArrayList<>();
Ma compréhension actuelle est que cela s'exprime some unknown type that extends Foo. Je suppose que cela signifie que tous les objets qui sont une sous-classe de Foopeuvent être ajoutés à cette liste; ce qui signifie qu'il n'y a pas de différence entre ArrayList<Foo>et ArrayList<? extends Foo>.
Pour tester cela, j'ai essayé d'écrire le code suivant
ArrayList<? extends Foo> subFoos = new ArrayList<>();
subFoos.add(new Foo());
subFoos.add(new Bar());
mais a été invité avec l'erreur de compilation suivante
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)
Sur la base de ma compréhension actuelle, je peux voir pourquoi je ne pourrais pas être en mesure d'ajouter un Fooà une liste de <? extends Foo>, car ce n'est pas une sous-classe en soi; mais je suis curieux de savoir pourquoi je ne peux pas ajouter un Barà la liste.
Où est le trou dans ma compréhension?
<? extends Foo>est une classe spécifique et inconnue qui s'étend Foo. Une opération avec cette classe n'est légale que si elle est légale pour n'importe quelle sous-classe de Foo.