Ich habe eine abstrakte Klasse Either<A,B>
mit den Unterklassen Left<A,B>
(ein Wrapper für ein A
) und Right<A,B>
(ein Wrapper für ein B
), also im Prinzip eine typsichere Version einer Union aus C/C++. Nun wollte ich eine Methode schreiben, die aus einer Liste von Either
s nur die “linken” Werte extrahiert. Fehlversuch:
static <A> List<A> lefts(List<Either<A,?> list) {
...
}
...
List<Either<String,Integer>> eithers = ...
List<String> strings = lefts(eithers); //<--------- Bumm!!!
java: method lefts in class org.highj.data.collection.Either<A,B> cannot be applied to given types;
required: org.highj.data.collection.List<org.highj.data.collection.Either<A,?>>
found: org.highj.data.collection.List<org.highj.data.collection.Either<java.lang.String,java.lang.Integer>>
reason: cannot infer type-variable(s) A
(argument mismatch; org.highj.data.collection.List<org.highj.data.collection.Either<java.lang.String,java.lang.Integer>> cannot be converted to org.highj.data.collection.List<org.highj.data.collection.Either<A,?>>)
Die Lösung ist, die Methoden-Signatur auf static <A> List<A> lefts(List<? extends Either<A,?>> list)
zu ändern. Nun dachte ich eigentlich, dass ich Wildcards einigermaßen begriffen habe, aber das verstehe ich beim besten Willen nicht. Wieso kann List<Either<A,?>>
nicht mit einer List<Either<String,Integer>>
aufgerufen werden, und warum klappt es dann mit dem zusätzlichen ? extends ...
?