Java Reference
In-Depth Information
Generic Method
maximum
and Specifying a Type Parameter's Upper Bound
Generic method
maximum
(lines 17-28) uses type parameter
T
as the return type of the
method (line 17), as the type of method parameters
x
,
y
and
z
(line 17), and as the type
of local variable
max
(line 19). The type-parameter section specifies that
T
extends
Comparable<T>
—only objects of classes that implement interface
Comparable<T>
can be
used with this method.
Comparable<T>
is known as the type parameter's
upper bound
. By
default,
Object
is the upper bound, meaning that an object of any type can be used. Type-
parameter declarations that bound the parameter always use keyword
extends
regardless
of whether the type parameter extends a class or implements an interface. The upper
bound may be a comma-separated list that contains zero or one class and zero or more in-
terfaces.
Method
maximum
's type parameter is more restrictive than the one specified for
print-
Array
in Fig. 20.3, which was able to output arrays containing any type of object. The
Comparable<T>
restriction is important, because not all objects can be compared. How-
ever,
Comparable<T>
objects are guaranteed to have a
compareTo
method.
Method
maximum
uses the same algorithm that we used in Section 6.4 to determine
the largest of its three arguments. The method assumes that its first argument (
x
) is the
largest and assigns it to local variable
max
(line 19). Next, the
if
statement at lines 21-22
determines whether
y
is greater than
max
. The condition invokes
y
's
compareTo
method
with the expression
y.compareTo(max)
, which returns a negative integer,
0
or a positive
integer, to determine
y
's relationship to
max
. If the return value of the
compareTo
is greater
than
0
, then
y
is greater and is assigned to variable
max
. Similarly, the
if
statement at lines
24-25 determines whether
z
is greater than
max
. If so, line 25 assigns
z
to
max
. Then line
27 returns
max
to the caller.
Calling Method
maximum
In
main
(lines 6-14), line 9 calls
maximum
with the integers
3
,
4
and
5
. When the compiler
encounters this call, it first looks for a
maximum
method that takes three arguments of type
int
. There's no such method, so the compiler looks for a generic method that can be used
and finds generic method
maximum
. However, recall that the arguments to a generic meth-
od must be of a
reference type
. So the compiler autoboxes the three
int
values as
Integer
objects and specifies that the three
Integer
objects will be passed to
maximum
. Class
Inte-
ger
(package
java.lang
) implements the
Comparable<Integer>
interface such that meth-
od
compareTo
compares the
int
values in two
Integer
objects. Therefore,
Integer
s are
valid arguments to method
maximum
. When the
Integer
representing the maximum is re-
turned, we attempt to output it with the
%d
format specifier, which outputs an
int
prim-
itive-type value. So
maximum
's return value is output as an
int
value.
A similar process occurs for the three
double
arguments passed to
maximum
in line 11.
Each
double
is autoboxed as a
Double
object and passed to
maximum
. Again, this is allowed
because class
Double
(package
java.lang
) implements the
Comparable<Double>
interface.
The
Double
returned by
maximum
is output with the format specifier
%.1f
, which outputs
a
double
primitive-type value. So
maximum
's return value is auto-unboxed and output as a
double
. The call to
maximum
in line 13 receives three
String
s, which are also
Compa-
rable<String>
objects. We intentionally placed the largest value in a different position in
each method call (lines 9, 11 and 13) to show that the generic method always finds the
maximum value, regardless of its position in the argument list.