Ich habe offenbar ein Missverständnis über den Unterschied zwischen <Foo>
und <? extends Foo>
. Nach meinem Verständnis, wenn wir hatten
ArrayList<Foo> foos = new ArrayList<>();
Dies zeigt an, dass Foo
dieser Array-Liste Objekte vom Typ hinzugefügt werden können. Da Unterklassen von Foo
ebenfalls vom Typ sind Foo
, können sie auch fehlerfrei hinzugefügt werden, wie durch dargestellt
ArrayList<Foo> foos = new ArrayList<>();
foos.add(new Foo());
foos.add(new Bar());
wo Bar extends Foo
.
Sagen wir, ich hätte definiert foos
als
ArrayList<? extends Foo> foos = new ArrayList<>();
Mein gegenwärtiges Verständnis ist, dass dies ausdrückt some unknown type that extends Foo
. Damit meine ich, dass alle Objekte, die zu einer Unterklasse gehören Foo
, zu dieser Liste hinzugefügt werden können. Das heißt, es gibt keinen Unterschied zwischen ArrayList<Foo>
und ArrayList<? extends Foo>
.
Um dies zu testen, habe ich versucht, den folgenden Code zu schreiben
ArrayList<? extends Foo> subFoos = new ArrayList<>();
subFoos.add(new Foo());
subFoos.add(new Bar());
wurde jedoch mit dem folgenden Kompilierungsfehler aufgefordert
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)
Nach meinem derzeitigen Verständnis kann ich sehen, warum ich möglicherweise kein zu Foo
einer Liste von hinzufügen kann <? extends Foo>
, weil es keine Unterklasse von sich selbst ist. aber ich bin gespannt, warum ich a nicht hinzufügen kannBar
der Liste .
Wo ist das Loch in meinem Verständnis?
<? extends Foo>
ist eine spezifische und unbekannte Klasse, die sich erweitertFoo
. Eine Operation mit dieser Klasse ist nur dann zulässig, wenn sie für eine Unterklasse von zulässig wäreFoo
.Antworten:
Wie Sie selbst festgestellt haben, wäre ein
ArrayList
deklariertes alsArrayList<? extends Foo> subFoos = new ArrayList<>();
nicht sehr nützlich.Um den Nutzen von zu sehen,
<? extends T>
überlegen Sie Folgendes:die später wie folgt verwendet werden können:
oder wie folgt:
Beachten Sie, dass keines der oben genannten
collect
Verfahren funktioniert hätte, wenn die Methode wie folgt deklariert worden wäre:quelle