I have a piece of code that I think should compile, but it doesn’t. Here is the code:
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 is an enum that implements MyInterface.
Why does calling myMethod(list) gives me argument type is not compatible?
If I change myMethod’s signature to:
public void myMethod(List<? extends Map<? extends MyInterface, String>> map)
then everything works fine, but I’m still puzzled and wish to know why the original
method signature does not work.
EnumMap<MyEnum, String>andEnumMap<? extends MyInterface, String>are different types (the former is a subtype of the latter). SoList<EnumMap<MyEnum, String>>andList<EnumMap<? extends MyInterface, String>>are not compatible with each other. In general,List<A>cannot be assigned toList<B>if A and B are different types, no matter what the relationship between A and B is (same applies to any generic type not just List). When you have a bounded type parameter, that is a different story; the compatibility takes the bounds into consideration.