Java Reference
In-Depth Information
11.5. Under the Hood: Erasure and Raw Types
As we have stated a number of times, for each generic type there is only
one class, no matter how many different parameterized types are formed
from it. This raises the question: What exactly is that type? Given a class
like
Cell<E>
, what type do
Cell<String>
and
Cell<Number>
share?
To determine the answer the compiler uses a process called
erasure
(be-
cause the compiler essentially erases all generic type information from
the compiled class). The erasure of a generic or parameterized type is
simply the unadorned type name. This is also known as the
raw type
(see
"
Raw Types, "Unchecked" Warnings, and Bridge Methods
" on page
745
)
.
For example, the erasure of
Cell<E>
is just
Cell
. The erasure of a type
variable is the erasure of its first bound. For example, the erasure of
E
in
<E>
is
Object
the implicit upper bound. The erasure of
E
in
<Eextends Number>
is the explicit upper bound of
Number
, as it is in
<Eextends Number& Clone-
able>
, because
Number
is the first bound. The compiler generates a class
definition for the erasure of a generic type by effectively replacing each
type variable with its erasure. When a parameterized type is used and
the type information from the erasure of the generic type doesn't match
what is expected, the compiler inserts a cast. For example, if you invoke
remove
on an object created as a
SingleLinkQueue<String>
and assign it to
a
String
reference, the compiler will insert a cast to
String
because the
erasure of the type variable in
SingleLinkQueue<E>
is just
Object
.
You need to understand the erasure process because it impacts your pro-
grams in two key areas:
•
The runtime actions that can involve generic types
•
Method overloading and overriding
We start with the runtime issues.