Java wildcard in multi-level generic type
generics, java, wildcard
Solution
Great question!
(In the following comments, w.r.t. a class generic in `E` like `Foo< E >`, define "covariant method" as a method that returns an `E` without having any parameters using `E`, and a "contravariant method" as the opposite: one which takes a formal parameter of type `E` but doesn't return a type involving `E`. [The real definition of these terms is more complicated, but never mind that for now.])
It seems that the compiler is trying to bind `T` to `Object` in the case of `f1`, because if you do
class Bar0 {
public static < T > void go( Foo< Foo< ? extends T > > f ) {
// can pass a Foo< T > to a contravariant method of f;
// can use any result r of any covariant method of f,
// but can't pass T to any contravariant method of r
}
}
then the `go(f1)` works, but now `go(f2)` doesn't, because even though `Foo< String > <: Foo< ? extends String >`, that does not imply that `Foo< Foo< String > > <: Foo< Foo< ? extends String > >`.
Here are a few modifications that compile for both `f1` and `f2`:
class Bar1 {
public static < T > void go( Foo< ? super Foo< T > > f ) {
// can't properly type the results of any covariant method of f,
// but we can pass a Foo< T > to any contravariant method of f
}
}
class Bar2 {
public static < T > void go( Foo< ? extends Foo< ? extends T > > f ) {
// can't pass a Foo< T > to a contravariant method of f;
// can use result r of any covariant method of f;
// can't pass a T to a contravariant method of r;
// can use result of covariant method of r
}
}
Problem
Why `Bar.go` is `OK` with argument `f2` but not with argument `f1`? ``` public class HelloWorld { public static void main(String[] args) { Foo<Foo<?>> f1 = new Foo<Foo<?>>(); Foo<Foo<String>> f2 = new Foo<Foo<String>>(); Bar.go(f1); // not OK Bar.go(f2); // OK } public static void p(Object o) { System.out.println(o); } } class Foo<E> { } class Bar { public static <T> void go(Foo<Foo<T>> f) { } } ``` Shouldn't the compiler automatically infer type `T` as `capture of ?` in both cases?