Java Reference
In-Depth Information
use it to describe the type of the array. And the way you introduce new
type variables in a method is to declare the method as a
generic meth-
od.
You declare a generic method by defining type variables between the
method modifiers and the method return type, much as you would de-
clare type variables for a generic class or interface. Here is how you
would actually define
toArray
as a generic method:
public <T> T[] toArray(T[] arr) {
Object[] tmp = arr;
int i = 0;
for (Cell<E> c = head;
c != null && i < arr.length;
c = c.getNext())
tmp[i++] = c.getElement();
return arr;
}
Notice that the type variable
T
is only used in the method header to con-
strain the parameter type and the return type to be the samewithin the
method body we don't really care what type
T
is. But also note that in
the method body we actually work with a local variable of type
Object[]
,
which refers to the actual array that is passed in. This is necessary be-
cause the array is of type
T
, but
getElement
returns
E
, and these are not
the same type
T
may be
Object
while
E
is
String
. We could cast
E
to
T
for
the cast must succeed if
T
and
E
are compatible, but such a cast would
be an
unchecked cast
and would produce a compiler warningsee "
Eras-
ure at Runtime
"
on page
267
s
o we bypass the problem by using the
Ob-
ject[]
variable.
By now you may be asking yourself: "Shouldn't there be some restric-
tion between the types
T
and
E
, since they must be compatible?" Logic-
ally, there could be such a restriction:
T
must be
E
or a supertype of
E
.
Unfortunately, there is no way to express this restriction. Only wildcards
can be given a lower type bound, so you cannot write
<Tsuper E>
as a
type variable. In any case, such a restriction is not strictly necessary.