我遇到一個奇怪的問題,用下面的代碼(當然,不是正是此代碼):好奇類型的錯誤
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
),編譯器能夠推斷正確的協變類型,因爲它有兩個可供選擇的子類型,我相信。但爲什麼不是編譯器能夠編譯第一個聲明,但是對於第二個聲明可以嗎?
謝謝。當你考慮它的時候很明顯,而不是當實際的類型簽名比例子中更復雜時:) – dm3