So, let's say i have a simple list if Integers:
List<Integer> intList = new ArrayList<>();
intList.add(1);
intList.add(2);
// intList.add("zxc"); // this will obviously fail
Now let's wrap the list inside another list:
List<List<Integer>> listOfListOfInt = new ArrayList<>();
listOfListOfInt.add(intList);
It's all fine. Now let's create the method
private static void method1(List<? extends List> cont) { // [1]
List<? super Date> data = cont.get(0); // [2]
data.add(new Date());
}
Basically i'm adding DATE to the first list in the list, because i'm telling it to treat that list as List<? super Date>
.
And it works because of the type erasure, of course:
method1(listOfListOfInt);
System.out.println(intList);
prints [1, 2, Tue Jun 14 23:41:15 BST 2016]
, so my List<Integer>
now has a Date in it.
Now i understand what's going on, because of the type erasure the List<? extends List>
becomes just a List, and then it's up to me what to put in it, so i'm putting Date.
Now the question i don't quite understand is that why there is no warning of "Unchecked assignment/calls" at all? According to the java compiler that code is perfectly type safe?
It will give the warning if in the method1 you'll replace List<? extends List>
to just a List<List>
for example, or if you'll replace List<? super Date>
with just a List
, and so on, generally you'll be warned about unchecked assignments/calls. But in this case you won't, all is fine.
UPDATE: Apparently there's warning by the compiler, but Intellij Idea refuses to show it for some reason. I have "Unchecked warning" inspection set without ignoring anything. And all settings are defaults anyway i think.
IntelliJ IDEA 2016.1.3 Build #IC-145.1617, built on June 3, 2016 JRE: 1.8.0_77-b03 x86 JVM: Java HotSpot(TM) Server VM by Oracle Corporation
Update2: it's not a duplicate, as the question is not about the functionality of raw types but about the lack of warning in this particular case. And it turns out it's just an IDE quirk.
>`.
– Eugene Jun 14 '16 at 22:56