次のコードを検討してください
class SomeClass {
}
class GenericsExample<E extends SomeClass> {
public void createError() {
process(new SomeClass()); //Compiler error!
}
public void createWorking() {
E some = new SomeClass(); //Compiler error!
process(some);
}
public void process(E object) {
}
}
public class Sandbox {
public void run() {
new GenericsExample<SomeClass>().process(new SomeClass()); //Not a compiler error?!
new GenericsExample().process(new SomeClass()); //Still not a compiler error?!
}
}
最初のエラーのメッセージ (2 番目のエラーは本質的に同じものです)
required: E
found: SomeClass
reason: actual argument SomeClass cannot be converted to E by method invocation conversion
where E is a type-variable:
E extends SomeClass declared in class GenericsExample
これは SomeClass を E にキャストすることで修正できますが、なぜそうしなければならないのでしょうか? メソッドが引数として E を取り、E が SomeClass を拡張する場合、引数として SomeClass を受け入れるべきではありませんか? これが警告ではなくコンパイラ エラーなのはなぜですか?
また、ジェネリック型を宣言していない場合でも、これが外部クラスに適用されないのはなぜですか? GenericsExample と Sandbox でルールが大きく異なるのはなぜですか?