Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

heap polution, java

Tags:

java

generics

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;

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

my question is about the part i made bold. I understand that in line 2 heap pollution occurs cause l being of List references an object of type List. But when add method is called on l reference shouldn't it expect Number type instead of String as l is reference to ArrayList. Or is it, that after ls=l the space in heap is made of List<String> also for the l reference? in this case makes sense what java docs says in the part made in bold

like image 401
tomaas Avatar asked Aug 19 '11 08:08

tomaas


3 Answers

But when add method is called on l reference shouldn't it expect Number type instead of String as l is reference to ArrayList.

List l is just declared as an untyped List. So the compiler will let you put in whatever you like (and warn about it), and let you assign it to an incompatible List<String> variable (and warn about it).

If you said List<Number> l, the compiler would enforce the proper types (and not let you assign it to ls).

No matter what generic types you declare or not declare, this has no effect at runtime. To maintain backwards compatibility, generics are a complete compile-time-only feature.

Or is it, that after ls=l the space in heap is made of List also for the l reference??

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).

like image 192
Thilo Avatar answered Sep 29 '22 10:09

Thilo


The error is in the first line. You declared l as a non type-safe list. Replace your first line by this:

List<Number> l = new ArrayList<Number>();
like image 33
home Avatar answered Sep 29 '22 10:09

home


Consider, what does the compiler know about this line:

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

It knows it has l, what it l? it's

List l

no specification of what type it can take. The line

List<String> ls = l;

has no effect on l, it is not the cause of the symptom you ask about, it's showing a different kind of problem.

like image 39
djna Avatar answered Sep 29 '22 09:09

djna