The JavaTM Tutorial
Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail > Start of Lesson Search
Feedback Form

Trail: Learning the Java Language
Lesson: Classes and Inheritance

Wildcard Types

To get around the conundrum posed by the first version of the printAll method you can specify that the argument to printAll is a collection whose element type matches anything, written as Collection<?>:
public void printAll(Collection<?> c) {
    for (Object o : c) {
        System.out.println(o);
    }
}
The ? type is known as a wildcard type. You can always extract objects from this collection because the returned type is always guaranteed to be Object. However, you cannot add objects to this collection, because ? stands for some unknown type and it's not possible to know if the type of the object you want to add is a subtype of the unknown type. The only exception is null, which is a member of every type.

You can also constrain (or bound) the wildcard by a type. Bounded wildcards are useful when you have partial knowledge about the type argument. For example, suppose you have a class hierarchy consisting of a geometric shape (Shape) and its subtypes (Circle, Rectangle, and so on). The drawing program that references these objects invokes a method drawAll to draw a collection of these shapes:

public void drawAll(Collection<Shapes> shapes) {
    for (Shape s: shapes) {
        s.draw();
    }
}
Since we have seen that it is not legal to pass in a subtype of Shape (for example, Circle) as the type argument for the generic collection passed to drawAll, this method has limited usefulness: for example, it cannot be called with Collection<Circle>. To enable passing a subtype of Shape as the type argument, you could express the type parameter of the shape collection as a wildcard. However, since we know that the type argument will be some type of shape, the wildcard should be bounded by the superclass Shape as follows:
void drawAll(Collection<? extends Shapes> shapes) { ... }
This allows drawAll to accept collections of any subclass of Shape.

In summary, a wildcard with an upper bound is specified as <? extends Type> and stands for all types that are subtypes of Type. It is also possible to constrain a wildcard with a lower bound. A wildcard with a lower bound is specified as <? super Type> and stands for all types that are supertypes of Type. Note that just as it is not possible to add an object to a collection of unknown type, it is also not legal to add an object to a collection of an unknown type that has a bound.


Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail > Start of Lesson Search
Feedback Form

Copyright 1995-2005 Sun Microsystems, Inc. All rights reserved.