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
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).
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>();
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With