The easy answer is that deeper-level wildcards cannot be replaced with a variable of type
void foo( List<List<?>> arg )
very different from
<T> void foo( List<List<T>> arg)
This is because the substitution capture transformation applies only to level 1 wildcards. Let's talk about it.
Due to the extensive capture conversion, in most places, the compiler treats wildcards as if they were type variables. Therefore, it is true that a programmer can replace a wildcard with type variables in such places, a kind of manual capture conversion.
Since the type variable created by the compiler to convert the capture is not available to the programmer, this has the limiting effect mentioned by @josefx. For example, the compiler treats a List<?> Object as a List<W> object; since W is internal to the compiler, although it has an add(W item) method, it is not possible for the programmer to call it because it does not have an element of type W However, if a programmer "manually" converts a wildcard into a variable of type T , he can have an element of type T and call add(T item) on it.
Another rather random case when a wildcard cannot be replaced with a variable of the type:
class Base List<? extends Number> foo() class Derived extends Base List<Integer> foo()
Here foo () is overridden by the covariant return type, since List<Integer> is a subtype of List<? extends Number List<? extends Number . This will not work if the wildcard is replaced with a type variable.
irreputable
source share