1.1 example
import java.util.*;
public class LOLUnknowns1 {
static void probablyIllegal(List<List<?>> lol, List<?> list) {
lol.add(list); // this compiles just fine
}
}
How come this 1.1 code compile if we may end up having List<List<Integer>> lol and a List<String> list?
this following code snippet: 1.2 example
import java.util.*;
public class TwoListsOfUnknowns2 {
static void doSomethingIllegal(List<?> list1, List<?> list2) {
list1.addAll(list2); // DOES NOT COMPILE as expected!!!
}
}
1.1 example baffles me, how is that possible to be compiled just fine?
I wnat to know the specific reason why a code compiled when it was expected not to from my understanding
How come this 1.1 code compile if we may end up having
List<List<Integer>> lol
and aList<String> list
?
You can not pass a List<List<Integer>>
to an argument of type List<List<?>>
. If you try:
probablyIllegal(new ArrayList<List<Integer>>(), new ArrayList<String>());
you get
The method
probablyIllegal(List<List<?>>, List<?>)
in the typeLOLUnknowns1
is not applicable for the arguments(ArrayList<List<Integer>>, ArrayList<String>
).
The reason is that even though a List<Integer>
is a subtype of List<?>
, List<List<Integer>>
is not a subtype of List<List<?>>
, just like, even though String
is a subtype of Object
, List<String>
is not a subtype of List<Object>
.
If you want to be able to pass a List<List<Integer>>
, you need to declare the argument to be of type List<? extends List<?>>
:
static void probablyIllegal(List<? extends List<?>> lol, List<?> list) {
lol.add(list);
}
After that change, the compiler will accept your call, but reject your method implementation:
The method
add(capture#1-of ? extends List<?>)
in the typeList<capture#1-of ? extends List<?>>
is not applicable for the arguments(List<capture#2-of ?>)
The error message is a bit cryptic (you need to read up on wildcard capture to understand it), but it basically says that you can't add the List<?>
to a List<? extends List<?>>
because you don't know what kind of elements lol
contains, and therefore can not know that list
is of a compatible type.
To conclude, you can either specify a specific element type for the List
, in which case you can add
, but not use a List
of a different type, or you can leave the element type of the List
unspecified, in which case you can use any List
, but not add
anything to it. Either way, nothing bad happens.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With