Java Reference
In-Depth Information
and
4.1
are
autoboxed
as
Double
objects. Line 12 declares and creates an
ArrayList
object
that stores
Number
s and assigns it to variable
numberList
.
Lines 14-15 traverse array
numbers
and place each element in
numberList
. Line 17
outputs the contents of the
ArrayList
as a
String
. This statement implicitly invokes the
ArrayList
's
toString
method, which returns a
String
of the form
"[
elements
]"
in which
elements
is a comma-separated list of the elements'
String
representations. Lines 18-19
display the sum of the elements that is returned by the call to method
sum
.
Method
sum
(lines 23-32) receives an
ArrayList
of
Number
s and calculates the total
of the
Number
s in the collection. The method uses
double
values to perform the calcula-
tions and returns the result as a
double
. Lines 28-29 use the enhanced
for
statement,
which is designed to work with both arrays and the collections of the Collections Frame-
work, to total the elements of the
ArrayList
. The
for
statement assigns each
Number
in
the
ArrayList
to variable
element
, then uses
Number
method
doubleValue
to obtain the
Number
's underlying primitive value as a
double
value. The result is added to
total
. When
the loop terminates, the method returns the
total
.
Implementing Method
sum
With a Wildcard Type Argument in Its Parameter
Recall that the purpose of method
sum
in Fig. 20.13 was to total any type of
Number
s stored
in an
ArrayList
. We created an
ArrayList
of
Number
s that contained both
Integer
and
Double
objects. The output of Fig. 20.13 demonstrates that method
sum
worked properly.
Given that method
sum
can total the elements of an
ArrayList
of
Number
s, you might ex-
pect that the method would also work for
ArrayList
s that contain elements of only one
numeric type, such as
ArrayList<Integer>
. So we modified class
TotalNumbers
to create
an
ArrayList
of
Integer
s and pass it to method
sum
. When we compile the program, the
compiler issues the following error message:
sum(java.util.ArrayList<java.lang.Number>) in TotalNumbersErrors
cannot be applied to (java.util.ArrayList<java.lang.Integer>)
Although
Number
is the superclass of
Integer
, the compiler doesn't consider the type
Array-
List<Number>
to be a superclass of
ArrayList<Integer>
. If it were, then every operation we
could perform on
ArrayList<Number>
would also work on an
ArrayList<Integer>
. Con-
sider the fact that you can add a
Double
object to an
ArrayList<Number>
because a
Double
is a
Number
, but you cannot add a
Double
object to an
ArrayList<Integer>
because a
Dou-
ble
is not
an
Integer
. Thus, the subtype relationship does not hold.
How do we create a more flexible version of the
sum
method that can total the elements
of any
ArrayList
containing elements of any subclass of
Number
? This is where
wildcard
type arguments
are important. Wildcards enable you to specify method parameters, return
values, variables or fields, and so on, that act as supertypes or subtypes of parameterized types.
In Fig. 20.14, method
sum
's parameter is declared in line 50 with the type:
ArrayList<?
extends
Number>
A wildcard type argument is denoted by a question mark (
?
), which by itself represents an
“unknown type.” In this case, the wildcard extends class
Number
, which means that the wild-
card has an upper bound of
Number
. Thus, the unknown-type argument must be either
Num-
ber
or a subclass of
Number
. With the parameter type shown here, method
sum
can receive
an
ArrayList
argument that contains any type of
Number
, such as
ArrayList<Integer>
(line
20),
ArrayList<Double>
(line 33) or
ArrayList<Number>
(line 46).