Generics are not covariant. Zum Beispiel:
List<Integer> l1;
List<Number> l2;
l1 = l2; // incompatible types
l2 = l1; // also incompatible
Allerdings bieten wildcarded Arten eine Art und Weise Kovarianz auszudrücken:
List<? extends Integer> l1;
List<? extends Number> l2 = l1; //legal
l1
als List
von einige unbekannte Art ausgedrückt werden, die oder Integer
erstreckt ist. Ähnlich ist l2
ein List
eines Typs, der Number
ist oder sich erstreckt. Da Integer
Number
erweitert, weiß der Compiler, l1
zu l2
zuweisen muss in Ordnung sein.
Diese Situation ist anders:
<S extends Number, U extends Integer> void someMethod() {
List<U> l1;
List<S> l2 = l1; //incompatible types
}
S
und U
Typ Parameter sind, dh sie einige spezifische Art Argumente von Anrufern von someMethod
(oder Typ Schlußfolgerungs) vorgesehen sind. Diese Typargumente könnten ein konkreter Typ wie Integer
oder ein Wildcard-Capture sein.
Während sie auch begrenzt sind, unterscheidet sich dies von der Verwendung von begrenzten Wildcards wie oben. Typparameter sind bei der Deklaration begrenzt - innerhalb des Methodenkörpers verstehen sie sich nicht zu ändern.Zum Beispiel, sagen wir mal, beide S
und U
-Integer
aufgelöst wurden durch den Aufruf:
this.<Integer, Integer>someMethod();
In diesem Fall können wir uns vorstellen, das Verfahren Körper wie folgt aussieht:
List<Integer> l1;
List<Integer> l2 = l1; // okay why not?
Diese Rechts sein würde, aber wir gerade passiert, um Glück zu haben. Es gibt viele Situationen, in denen es nicht wäre. Zum Beispiel:
this.<Double, Integer>someMethod();
Jetzt neu erfinden wir die Methode Körper:
List<Integer> l1;
List<Double> l2 = l1; // danger!
So können Sie sehen, dass ein beschränkter Typ-Parameter ein etwas viel anders aus einem beschränkten Platzhalter ist, die unterschiedlichen generische Typen erlaubt zu sein covariantly "getauscht":
List<Integer> l1;
List<Double> l2;
List<? extends Number> l3;
l3 = l1;
l3 = l2;
Können Sie zeigen, wie Sie sie zuvor für Ihr zweites Beispiel definieren? – Quetzalcoatl
@SaurabhAgarwal ist das nicht der Punkt? Warum funktioniert "irgendeine Unterklasse", aber eine _spezielle_ Unterklasse nicht? – Alnitak
public class WildcardsTest
{/ * Code oben in 2 dargestellt * /} – Razvan