mercredi 15 juin 2016

Raw types and type safety

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

Aucun commentaire:

Enregistrer un commentaire