In the following example:
public static void main(String[] args) {
List<String> b = new ArrayList<String>();
first(b);
second(b);
List<List<String>> a = new ArrayList<List<String>>();
third(a);
fourth(a); // doesnt work
}
private static <T> void first(List<T> a){
System.out.println("List of T");
}
private static void second(List<?> a){
System.out.println("List of anything ");
}
private static <T> void third(List<List<T>> a){
System.out.println("List of a List of T ");
}
private static void fourth(List<List<?>> a){
System.out.println("List of a List of anything ");
}
Why does the call to second(b) work, but the call to fourth(a) doesn't ?
I get the following error:
The method fourth(List<List<?>>) in the type `TestTest` is not applicable for the arguments (`List<List<String>>`)
A
List<List<String>>
isn't aList<List<?>>
.You should be able to put any
List<?>
into aList<List<?>>
, no matter what the?
. AList<List<String>>
will only accept aList<String>
.List<List<String>>
is not same asList<List<?>>
. Generics are invariant in nature. If you only doList<?>
and passList<String>
then it will work becauseList of Anything
can be represented byLists of String
.But
List of List of anything
can not be represented byList of List of String
.@Lukas Elder
has already specified case that will work. Here is the second case that will workIf you want to be able to call
fourth
with aList<List<String>>
argument, then you'll need to change your signature to this:The above will work because unlike
List<List<?>>
,List<? extends List<?>>
is compatible withList<List<String>>
. Think of it this way:The reasoning is simple. If you had
And then if you could call that method as such:
Where as
So here
Hence
List<? extends List<?>
is super type ofList<List<String>>
and assignable.So valid value to call your
fourth
method is below.