Given:
public class Testcase {
public static <E> List<List<E>> transform(List<List<E>> list) {
return list;
}
public static <E> List<List<? extends E>> transform2(List<List<? extends E>> list) {
return list;
}
public static void main(String[] args) {
List<List<Integer>> known = new ArrayList<>();
List<List<? extends Number>> unknown = new ArrayList<>();
transform(known); // works
transform(unknown); // fails
transform2(known); // fails
transform2(unknown); // works
}
}
The compiler accepts transform(known)
but complains:
cannot infer type-variable(s) E
(argument mismatch; List<List<? extends Number>> cannot be converted to List<List<E>>)
where E is a type-variable:
E extends Object declared in method <E>transform(List<List<E>>)
for transform(unknown)
. I get the opposite problem for transform2()
. I've consulted PECS and I believe that transform()
is the correct method declaration but I can't for the life of my figure out how to get a single method to handle both cases.
Note that this problem only occurs for multi-level Generics. List<? extends Number>
works just fine. The problem is not specific to Lists. You'll get it for Future<Task<X>>
and so on.
What method declaration will handle both bounded and unbounded Generics? And if it's not possible, why?