Java Reference
In-Depth Information
Erasure and the Upper Bound of a Type Parameter
When the compiler translates method
maximum
into bytecodes, it uses erasure to replace the
type parameters with actual types. In Fig. 20.3, all generic types were replaced with type
Ob-
ject
. Actually, all type parameters are replaced with the
upper bound
of the type parameter,
which is specified in the type-parameter section. Figure 20.6 simulates the erasure of method
maximum's types by showing the method's source code after the type-parameter section is
removed and type parameter
T
is replaced with the upper bound,
Comparable
, throughout
the method declaration. The erasure of
Comparable<T>
is simply
Comparable
.
1
public static
Comparable
maximum(
Comparable
x,
Comparable
y,
Comparable
z)
2
{
3
Comparable
max = x;
// assume x is initially the largest
4
5
if
(y.compareTo(max) >
0
)
6
max = y;
// y is the largest so far
7
8
if
(z.compareTo(max) >
0)
9
max = z;
// z is the largest
10
11
return
max;
// returns the largest object
12
}
Fig. 20.6
|
Generic method
maximum
after erasure is performed by the compiler.
After erasure, method
maximum
specifies that it returns type
Comparable
. However,
the calling method does not expect to receive a
Comparable
. It expects to receive an object
of the same type that was passed to
maximum
as an argument—
Integer
,
Double
or
String
in this example. When the compiler replaces the type-parameter information with the
upper-bound type in the method declaration, it also inserts
explicit cast operations
in front
of each method call to ensure that the returned value is of the type expected by the caller.
Thus, the call to
maximum
in line 9 (Fig. 20.5) is preceded by an
Integer
cast, as in
(Integer) maximum(
3
,
4
,
5
)
the call to
maximum
in line 11 is preceded by a
Double
cast, as in
(Double) maximum(
6.6
,
8.8
,
7.7
)
and the call to
maximum
in line 13 is preceded by a
String
cast, as in
(String) maximum(
"pear"
,
"apple"
,
"orange"
)
In each case, the type of the cast for the return value is
inferred
from the types of the meth-
od arguments in the particular method call, because, according to the method declaration,
the return type and the argument types match. Without generics, you'd be responsible for
implementing the cast operation.
A generic method may be overloaded like any other method.
A class can provide two or more
generic methods that specify the same method name but different method parameters. For
example, generic method
printArray
of Fig. 20.3 could be overloaded with another