我遇到了以下代码的一个奇怪问题(嗯,不完全是这段代码):
public class CompilationProblems1 {
static Box<Class<? extends AlcoholicBewerage>> brokenBoxOfOneBeer = boxOf(Beer.class);
static Box<? extends Class<? extends AlcoholicBewerage>> boxOfOneBeer = boxOf(Beer.class);
static Box<Class<? extends AlcoholicBewerage>> boxOfBeerAndVodka = boxOf(Beer.class, Vodka.class);
interface AlcoholicBewerage {}
class Beer implements AlcoholicBewerage {}
class Vodka implements AlcoholicBewerage {}
static class Box<T> {}
static <E> Box<E> boxOf(E e) {
return new Box<E>();
}
static <E> Box<E> boxOf(E e1, E e2) {
return new Box<E>();
}
}
第一个声明brokenBoxOfOneBeer
给出了编译错误:
found : lt.tool.CompilationProblems1.Box<java.lang.Class<lt.tool.CompilationProblems1.Beer>>
required: lt.tool.CompilationProblems1.Box<java.lang.Class<? extends lt.tool.CompilationProblems1.AlcoholicBewerage>>
static Box<Class<? extends AlcoholicBewerage>> brokenBoxOfOneBeer = boxOf(Beer.class);
此错误发生在 OpenJDK 6、Eclipse 和 IntelliJ 上。我知道这是类型推断器的限制。
在第三种情况下(boxOfBeerAndVodka
),我相信编译器能够推断出正确的协变类型,因为它有两个子类型可供选择。但是为什么编译器不能编译第一个声明,而第二个声明却可以呢?