ジェネリクスがらみで各種 Java コンパイラーの挙動が異なる件
自分でもまだエラーの原因を特定できていないので、とりあえずメモレベル。
import java.util.ArrayList; import java.util.List; public class Foo {} class X<T extends X<T>> {} class Y<T extends X<T>> {} class Fuga { <T extends X<T>> void foo(Y<T> y) {} void main() { List<Y<? extends X<?>>> list = new ArrayList<Y<? extends X<?>>>(); for (Y<? extends X<?>> e : list) { foo(e); } } }
コンパイラー | コンパイル結果 |
---|---|
javac (jdk1.5.0_16) | × |
javac (jdk1.6.0_21) | ○ |
ecj (eclipse 3.6.1, compilance level 1.5) | × |
ecj (eclipse 3.6.1, compilance level 1.6) | × |
javac のエラーメッセージ
[javac] Foo.java:15:
foo(Y ) (Fuga 内) を (Y >) に適用できません
[javac] foo(e);
[javac] ^
ecj のエラーメッセージ
Bound mismatch: The generic method foo(Y
) of type Fuga is not applicable for the arguments (Y >). The inferred type capture#1-of ? extends X is not a valid substitute for the bounded parameter >
import java.util.ArrayList; import java.util.List; public class Foo {} interface X<T extends X<T>> {} // ここを class -> interface に変更しただけ class Y<T extends X<T>> {} class Fuga { <T extends X<T>> void foo(Y<T> y) {} void main() { List<Y<? extends X<?>>> list = new ArrayList<Y<? extends X<?>>>(); for (Y<? extends X<?>> e : list) { foo(e); } } }
コンパイラー | コンパイル結果 |
---|---|
javac (jdk1.5.0_16) | × |
javac (jdk1.6.0_21) | ○ |
ecj (eclipse 3.6.1, compilance level 1.5) | ○ |
ecj (eclipse 3.6.1, compilance level 1.6) | ○ |
javac のエラーメッセージは変わらず。