Concepts of Programming Languages

(Sean Pound) #1

426 Chapter 9 Subprograms


Now, consider the following version of doIt, which has a bound on its
generic parameter:

public static <T extends Comparable> T doIt(T[] list) {

...
}


This defines a method that takes a generic array parameter whose elements are
of a class that implements the Comparable interface. That is the restriction, or
bound, on the generic parameter. The reserved word extends seems to imply
that the generic class subclasses the following class. In this context, however,
extends has a different meaning. The expression <T extends BoundingType>
specifies that T should be a “subtype” of the bounding type. So, in this context,
extends means the generic class (or interface) either extends the bounding class
(the bound if it is a class) or implements the bounding interface (if the bound is
an interface). The bound ensures that the elements of any instantiation of the
generic can be compared with the Comparable method, compareTo.
If a generic method has two or more restrictions on its generic type, they
are added to the extends clause, separated by ampersands (&). Also, generic
methods can have more than one generic parameter.
Java 5.0 supports wildcard types. For example, Collection<?> is a wild-
card type for collection classes. This type can be used for any collection type
of any class components. For example, consider the following generic method:

void printCollection(Collection<?> c) {
for (Object e: c) {
System.out.println(e);
}
}

This method prints the elements of any Collection class, regardless of the class
of its components. Some care must be taken with objects of the wildcard type.
For example, because the components of a particular object of this type have a
type, other type objects cannot be added to the collection. For example, consider:

Collection<?> c = new ArrayList<String>();

It would be illegal to use the add method to put something into this collection
unless its type were String.
Wildcard types can be restricted, as is the case with nonwildcard types.
Such types are called bounded wildcard types. For example, consider the follow-
ing method header:

public void drawAll(ArrayList<? extends Shape> things)

The generic type here is a wildcard type that is a subclass of the Shape class. This
method could be written to draw any object whose type is a subclass of Shape.
Free download pdf