In How Generics works in Java
section of this it says
Java compiler, when it sees code written using Generics it completely erases that code and covert it into raw type i.e. code without Generics. All type related information is removed during erasing. So your ArrayList becomes plain old ArrayList prior to JDK 1.5, formal type parameters e.g. or gets replaced by either Object or Super Class of the Type.
My question is about the last line - formal type parameters e.g. <K, V> or <E> gets replaced by either Object or Super Class of the Type
.
In which case are they replaced by Object and in which case they are replaced by the Super Class of the object type?
Update :
What happens when we have wild card like below?
List<? extends Foo>
You already know what the erasure is. The erasure is written |T|
, so |List<String>|
is List
. Type variables, meaning mentionings of formal type parameters, are erased to the erasure of their left-most bound. The most general form of a formal type parameter T
is T extends A1 & A2 & ...
, where A1
to An
are T
s bounds.
For Example
public abstract class Copyable<T extends Copyable<T> & Cloneable> {
public T copy() { /* ... */ }
}
The T
in copy would be erased to the erasure of its left-most bound. That is |Copyable<T>| = Copyable
.
Simpler bounds may be
class Enum<E extends Enum<E>>
: The left most bound is the single bound, the erasure is |Enum<E>| = Enum
.class ArrayList<E>
: E
really has an implicit bound of Object
(class ArrayList<E extends Object>
), so the erasure is |Object| = Object
.Edit: In case of a List<? extends Foo>
you'd be erasing the entire thing; and the erasure of List<? extends Foo>
is |List|
.