それではリストはなぜコード(以下)がコンパイルされるのでしょうか?確かにMyClass2
返す必要がありますかList<Integer>
?
public class Main {
public static void main(final String[] args) {
MyClass myClass = new MyClass();
List list = myClass.getList();
System.out.println(list);
System.out.println(list.get(0).getClass());
MyClass2 myClass2 = new MyClass2();
List list2 = myClass2.getList();
System.out.println(list2);
System.out.println(list2.get(0).getClass());
}
public interface Int1 {
public List getList();
}
public interface Int2 extends Int1 {
@Override
public List<Integer> getList();
}
public static class MyClass implements Int2 {
@Override
public List<Integer> getList() {
return Arrays.asList(1, 2, 3);
}
}
public static class MyClass2 implements Int2 {
@Override
public List getList() {
return Arrays.asList("One", "Two", "Three");
}
}
}
私がそれをしようとすると、List<String>
「java:Main.MyClass2は抽象的ではなく、Main.Int2の抽象メソッドgetList()をオーバーライドしない」というエラーが発生することに気づきました。上記の例でこれが得られない理由がよくわかりません。
注:私のプロジェクトでの問題の解決策は、インターフェース自体を一般的なものInt1<X>
にすることです(もちろん、私はこれよりも優れた名前を使用していますが、これは単なる例です)。
答えはJLS 7 5.5.1にあります。参照タイプのキャスト:
コンパイル時参照タイプS(ソース)とコンパイル時参照タイプT(ターゲット)が与えられた場合、以下のルールによるコンパイル時エラーが発生しない場合、キャスト変換はSからTに存在します。
Sがクラス型の場合:
If T is a class type, then either |S| <: |T|, or |T| <: |S|. Otherwise, a compile-time error occurs. Furthermore, if there exists a supertype X of T, and a supertype Y of S, such that both X and Y are provably distinct parameterized types
(§4.5)、XとYの消去が同じである場合、コンパイル時エラーが発生します。
あなたの場合List<Integer>
、そしてList<String>
明らかに異なるパラメータ化されたタイプであり、それらは両方とも同じ消去を持っています:List
。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加