Java compiler ignores type safety

public class POJO<T> { private List<Integer> integer = new ArrayList<Integer>(); public POJO() { integer.add(1); integer.add(2); } public List<Integer> getInteger() { return integer; } public static void main(String[] args) { POJO pojo = new POJO(); List<String> integer = pojo.getInteger(); // No compile error? System.out.println(integer); // prints [1, 2] } } 

How can the following line be compiled:

 List<String> integer = pojo.getInteger(); 

Provided that getInteger() is typed as follows

 public List<Integer> getInteger() 
+7
source share
3 answers

I found a link in JLS 4.8 that supports what @PeterLawrey says:

The type of constructor (§8.8), the instance method (§8.4, clause 9.4) or the non-static field (§8.3) of the raw type C, which is not inherited from its superclasses or superinterfaces, is the original type that corresponds to erasing its type in the general declaration corresponding to C.

So, all instance methods of your original POJO erased, including those that do not refer to the type T of POJO<T> , which means ( JLS 4.6 ):

Parameters of the method type [...] (§8.4.4) and the return type (§8.4.5) of the method are also erased if the signature of the method is [...] erased.

+7
source

Since pojo not declared as generic

 POJO pojo = new POJO(); 

the compiler assumes that you are using it in pre-code. those. when the generic files were added after writing the code. Therefore when you do

 List<String> integer = pojo.getInteger(); 

You get a warning, not an error.

i.e. If the type is not generic, all generic checks are disabled, not just those of the type that you did not give it. I believe this is for maximum backward compatibility.

For comparison.

 Map mapOfInteger = new Map(); // no generics Set<String> entries = map.entrySet(); // gives a warning, not an error. 

In this example, you can expect Set<Entry<K, V>> become Set<Entry> if it is not generic, but the compiler returns to consider a class that is not generic Set .

+7
source

This is an unverified task that is not considered a bug for compatibility reasons.

See Interacting with Legacy Code

In reality, the assignment is legal, but it generates an unverified warning.

+2
source

All Articles