Java Reference
In-Depth Information
argument. The only operation performed on the array elements in this example is to
output their
String
representation. Line 26 performs an
implicit
toString
call
on every
element
.
To work with generics, every element of the array must be an object of a class or inter-
face type.
Since all objects have a
toString
method, the compiler is satisfied that line 26
performs a
valid
operation for any object in
printArray
's array argument. The
toString
methods of classes
Integer
,
Double
and
Character
return the
String
representation of
the underlying
int
,
double
or
char
value, respectively.
Erasure at Compilation Time
When the compiler translates generic method
printArray
into Java bytecodes, it removes
the type-parameter section and
replaces the type parameters with actual types
. This process is
known as
erasure
. By default all generic types are replaced with type
Object
. So the com-
piled version of method
printArray
appears as shown in Fig. 20.4—there's only
one
copy
of this code, which is used for all
printArray
calls in the example. This is quite different
from similar mechanisms in other programming languages, such as C++'s templates, in
which a
separate copy of the source code
is generated and compiled for
every
type passed as
an argument to the method. As you'll see in Section 20.4, the translation and compilation
of generics is a bit more involved than what we've discussed in this section.
By declaring
printArray
as a generic method in Fig. 20.3, we eliminated the need for
the overloaded methods of Fig. 20.1 and created a reusable method that can output the
String
representations of the elements in any array that contains objects. However, this
particular example could have simply declared the
printArray
method as shown in
Fig. 20.4, using an
Object
array as the parameter. This would have yielded the same
results, because any
Object
can be output as a
String
. In a generic method, the benefits
become more apparent when you place restrictions on the type parameters, as we demon-
strate in the next section.
1
public static void
printArray(
Object
[] inputArray)
2
{
3
// display array elements
4
for
(
Object
element : inputArray)
5
System.out.printf(
"%s "
, element);
6
7
System.out.println();
8
}
Fig. 20.4
|
Generic method
printArray
after the compiler performs erasure.
20.4
Additional Compile-Time Translation Issues:
Let's consider a generic method in which type parameters are used in the return type and in
the parameter list (Fig. 20.5). The application uses a generic method
maximum
to determine
and return the largest of its three arguments of the same type. Unfortunately,
the relational
operator
>
cannot be used with reference types
. However, it's possible to compare two objects
of the same class if that class implements the generic
interface
Comparable<T>
(from package
java.lang
). All the type-wrapper classes for primitive types implement this interface.