Java Reference
In-Depth Information
Capture conversion is designed to make wildcards more useful. To understand the mo-
tivation, let's begin by looking at the method java.util.Collections.reverse() :
public static void reverse(List<?> list);
The method reverses the list provided as a parameter. It works for any type of list, and
so the use of the wildcard type List<?> as the type of the formal parameter is entirely
appropriate.
Now consider how one would implement reverse() :
Click here to view code image
public static void reverse(List<?> list) { rev(list); }
private static <T> void rev(List<T> list) {
List<T> tmp = new ArrayList<T>(list);
for (int i = 0; i < list.size(); i++) {
list.set(i, tmp.get(list.size() - i - 1));
}
}
The implementation needs to copy the list, extract elements from the copy, and insert
them into the original. To do this in a type-safe manner, we need to give a name, T , to
the element type of the incoming list. We do this in the private service method rev() .
This requires us to pass the incoming argument list, of type List<?> , as an argument to
rev() . In general, List<?> is a list of unknown type. It is not a subtype of List<T> , for any
type T . Allowing such a subtype relation would be unsound. Given the method:
public static <T> void fill(List<T> l, T obj)
the following code would undermine the type system:
Click here to view code image
List<String> ls = new ArrayList<String>();
List<?> l = ls;
Collections.fill(l, new Object()); // not legal - but assume it was!
String s = ls.get(0); // ClassCastException - ls contains
// Objects, not Strings.
So, without some special dispensation, we can see that the call from reverse() to rev()
would be disallowed. If this were the case, the author of reverse() would be forced to
write its signature as:
public static <T> void reverse(List<T> list)
This is undesirable, as it exposes implementation information to the caller. Worse, the
designer of an API might reason that the signature using a wildcard is what the callers
Search WWH ::




Custom Search