Cyk*_*ker 7 java generics wildcard
为什么Bar.go是OK有争论f2,但不与论证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) {
}
}
Run Code Online (Sandbox Code Playgroud)
不应编译器自动推断类型T为capture of ?在这两种情况下?
好问题!
E(在下面的注释中,对于like中的类泛型Foo< E >,将“协变方法”定义为一种E使用 不带任何参数返回 的方法E,而“逆变方法”则相反:它采用类型的形式参数,E但不使用任何参数。不返回涉及 的类型E。[这些术语的真正定义更复杂,但现在不用介意。])
编译器似乎试图在 的情况下T绑定,因为如果你这样做Objectf1
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
}
}
Run Code Online (Sandbox Code Playgroud)
然后go(f1)有效,但现在go(f2)不行,因为即使如此Foo< String > <: Foo< ? extends String >,这并不意味着Foo< Foo< String > > <: Foo< Foo< ? extends String > >。
f1以下是针对和进行编译的一些修改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
}
}
Run Code Online (Sandbox Code Playgroud)