次のコードで奇妙な問題が発生しました(まあ、正確にはこのコードではありません):
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で発生します。これが型推論の制限であることを理解しています。
3番目のケース(boxOfBeerAndVodka
)では、コンパイラーは2つのサブタイプから選択できるため、正しい共変型を推測できます。しかし、なぜコンパイラは最初の宣言をコンパイルできないのに、2番目の宣言は問題ないのでしょうか。