There is no logical reason why we should not be able to pass it a list referenced through a wildcard type:
static void processList(List<?> list) {
List<?> slist = Collections.synchronizedList(list);
// ... process the list
}
To do so is quite safeand quite convenient!
Although in general you cannot use a List<?> where a List
represented by the wildcard is not known to be compatible with T, a special rule bridges the gap that would
otherwise exist between wildcard types and the type variables of generic methods. This rule allows (under the
right circumstances) the capture of the wildcard to be represented as some unknown generic type X and then
to infer in the call that T is X. You don't actually need to know what X iswhatever it is, the resulting use of the
list is guaranteed to be type-safe.
This conversion of the capture of the wildcard to the type T is known as capture conversion and it
complements the other type conversions that we discussed in Section 9.4 on page 216.
For capture conversion to apply, there must be a unique mapping between the capture of the wildcard and the
type variable involved. This leads to some general restrictions on when capture conversion can apply.
First, capture conversion won't apply if the type parameter is used with more than one method parameter.
Consider a utility method that merges two lists:
static
/ ... /
}
If you try to pass an argument of type List<?> for first and second it will faileven if you passed the
same reference. The problem is that the process for resolving the method call will essentially replace the type
of the first argument with X, the type of the second argument with Y, and then see if T is uniquely determined.
But because X is not the same as Y this will not be the case.
Second, you can only apply capture conversion if the type variable is defined at the top-level of the generic
type. For example, suppose you had the method
static
/ ... /
}
and you tried to invoke it with an argument of type List<List<?>>. The capture of the wildcard would not
uniquely determine an element type for the outer List. The method requires a List with elements that are
all the same type, but a List with an element type of List<?> could contain a List
List
Finally, as usual you cannot use a wildcard reference anywhere that the type of the wildcard needs to be
known. For example, given the method