Java Reference
In-Depth Information
11
/** Find the maximum in a stack of numbers */
12
public static double
max(GenericStack<Number> stack) {
GenericStack<Number>
type
13
double
max = stack.pop().doubleValue();
// Initialize max
14
15
while
(!stack.isEmpty()) {
16
double
value = stack.pop().doubleValue();
17
if
(value > max)
18 max = value;
19 }
20
21
return
max;
22 }
23 }
The program in Listing 19.7 has a compile error in line 8 because
intStack
is not an instance
of
GenericStack<Number>
. Thus, you cannot invoke
max(intStack)
.
The fact is that
Integer
is a subtype of
Number
, but
GenericStack<Integer>
is not
a subtype of
GenericStack<Number>
. To circumvent this problem, use wildcard generic
types. A wildcard generic type has three forms:
?
and
? extends T
, as well as
? super T
,
where
T
is a generic type.
The first form,
?
, called an
unbounded wildcard
, is the same as
? extends Object
. The
second form,
? extends T
, called a
bounded wildcard
, represents
T
or a subtype of
T
. The
third form,
? super T
, called a
lower-bound wildcard
, denotes
T
or a supertype of
T
.
You can fix the error by replacing line 12 in Listing 19.7 as follows:
unbounded wildcard
bounded wildcard
lower-bound wildcard
public static double
max(GenericStack<?
extends
Number> stack) {
<? extends Number>
is a wildcard type that represents
Number
or a subtype of
Number
,
so it is legal to invoke
max(new GenericStack<Integer>())
or
max(new
GenericStack<Double>())
.
Listing 19.8 shows an example of using the
?
wildcard in the
print
method that prints
objects in a stack and empties the stack.
<?>
is a wildcard that represents any object type. It
is equivalent to
<? extends Object>
. What happens if you replace
GenericStack<?>
with
GenericStack<Object>
? It would be wrong to invoke
print(intStack)
,
because
intStack
is not an instance of
GenericStack<Object>
. Please note that
GenericStack<Integer>
is not a subtype of
GenericStack<Object>
, even though
Integer
is a subtype of
Object
.
L
ISTING
19.8
AnyWildCardDemo.java
1
public class
AnyWildCardDemo {
2
public static void
main(String[] args ) {
3 GenericStack<Integer> intStack =
new
GenericStack<>();
4 intStack.push(
1
);
// 1 is autoboxed into new Integer(1)
5 intStack.push(
2
);
6 intStack.push(
-2
);
7
8 print(intStack);
9 }
10
11
/** Prints objects and empties the stack */
12
public static void
print(GenericStack<?> stack) {
13
while
(!stack.isEmpty()) {
14 System.out.print(stack.pop() +
" "
);
15 }
16 }
17 }
GenericStack<Integer>
type
wildcard type
Search WWH ::
Custom Search