Heap protection, java

List l = new ArrayList<Number>(); List<String> ls = l; // unchecked warning l.add(0, new Integer(42)); // another unchecked warning String s = ls.get(0); // ClassCastException is thrown 

The java documentation says:

In addition, a heap pollution situation occurs when the l.add method is called. The static type of the second formal parameter of the add method is String, but this method is called with the actual parameter of another type, Integer . However, the compiler still allows this method call. Due to type erasure, the type of the second formal parameter of the add method (which is defined as List.add (int, E)) becomes an object. Therefore, the compiler allows you to call this method because after erasing the type, the l.add method can add any type Object, including an Integer

my question is about the part made in bold. I understand that in line 2 there is a heap pollution, because l is a reference to a list of objects of type List. But when the add method is called in l reference, you should not expect that the Number type instead of String is l, this is a reference to ArrayList. Or is it that after ls = l the heap space is made from List<String> also for l links? in this case it makes sense what the Java document says in the part in bold

+6
source share
3 answers

But when the add method is called in an l-reference, you should not expect that the type Number instead of String is equal to l is a reference to ArrayList.

List l declared as an untyped list. Therefore, the compiler will allow you to insert whatever you like (and warn about it) and let you assign it to an incompatible List<String> variable (and warn about it).

If you told List<Number> l , the compiler will use the appropriate types (and not let you assign it ls ).

Regardless of what types of ads you declare or do not declare, this does not affect the execution time. To maintain backward compatibility, generics are a complete compile-time function.

Or is it that after ls = l the heap space is made from List also for l links?

If you say

 List l = new ArrayList<Integer>(); List<String> ls = l; Object x = ls; Collection<?> c = (Collection) x; 

you have four different variables (with four different type declarations), but they all point to the same data (the same object on the heap).

+7
source

Error in the first line. You declared l as an unsafe list. Replace the first line as follows:

 List<Number> l = new ArrayList<Number>(); 
+1
source

Consider what the compiler knows about this line:

 l.add(0, new Integer(42)); 

He knows what it l, what is it? this is

 List l 

there is no specification of what type it can accept. Line

 List<String> ls = l; 

does not affect l, this is not the cause of the symptom you are asking for, it shows a different problem.

+1
source

Source: https://habr.com/ru/post/895396/


All Articles