2009-06-27 8 views
1

私はコンパイルすべきだと思うコードを持っていますが、それはありません。ここでは、コードは次のとおり具体的なEnumMapオブジェクトのリストをgenericに渡すEnumMapパラメータのリストによりコンパイルエラーが発生する

public class Program { 
public void myMethod(List<EnumMap<? extends MyInterface, String>> map) 
{ 

} 

public void caller() 
{ 
    EnumMap<MyEnum, String> map = new EnumMap<MyEnum, String>(MyEnum.class); 

    List<EnumMap<MyEnum, String>> list = new LinkedList<EnumMap<MyEnum, String>>(); 

    myMethod(list); //error argument type is not compatible 

} 

}

MyEnumはMyInterfaceを実装する列挙です。

myMethod(list)の呼び出しで私の引数型が互換性がないのはなぜですか?

私はMyMethodはの署名を変更する場合:

public void myMethod(List<? extends Map<? extends MyInterface, String>> map) 

その後、すべてが正常に動作しますが、私はまだ困惑してると、元 メソッドのシグネチャが動作しない理由を知りたいです。

答えて

1

EnumMap<MyEnum, String>およびEnumMap<? extends MyInterface, String>は、異なるタイプです(前者は後者のサブタイプです)。したがってList<EnumMap<MyEnum, String>>List<EnumMap<? extends MyInterface, String>>は互いに互換性がありません。一般的に、AとBの関係が何であっても、AとBが異なるタイプの場合はList<A>List<B>に割り当てることはできません(Listだけでなく、同じジェネリックタイプにも同じです)。境界型パラメータがある場合、それは別の話です。互換性は境界を考慮に入れます。

2

ので、

enum MyEnum implements MyInterface { ...} 
... 
List<EnumMap<MyEnum, String>> as = new ArrayList<EnumMap<MyEnum, String>>(); 
List<EnumMap<? extends MyInterface, String>> bs; 

与えられた私たちは、bs = asを割り当てることができるでしょうか?

は今、同じオブジェクトが、明らかに異なる種類の

enum OtherEnum implements MyInterface { XXX } 
... 
EnumMap<OtherEnum, String> otherMap = 
    new EnumMap<OtherEnum, String>(OtehrEnum.class); 
otherMap.put(OtherEnum.XXX, ""); 
bs.set(0, otherMap); 
EnumMap<MyEnum, String> myMap = as.get(0); 
MyEnum xxx = myMap.keys().iterator().next(); 

otherMapmyMapポイントを仮定します。さらに悪いことに、xxxMyEnumですが、タイプOtherEnumのオブジェクトを指しています。

多型の存在下でのポインタへのポインタは困難です。

+0

ありがとう、私はあなたが言っていることを理解していますが、方法の署名をpublic void myMethod(List <?extends Map <?extends MyInterface、String >> map)に変更すると、エラーは消えますか?エラーがあってはならないのですか? – Alvin

関連する問題