将具体的EnumMap对象列表传递给通用的EnumMap参数列表会导致编译错误

时间:2009-06-27 23:48:35

标签: java generics

我有一段我认为应该编译的代码,但事实并非如此。这是代码:

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)
然后一切正常,但我仍然感到困惑,并希望知道原来的原因 方法签名不起作用。

2 个答案:

答案 0 :(得分: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指向相同的对象,但明显不同的类型。更糟糕的是,xxx是tyoe MyEnum,但指的是OtherEnum类型的对象。

在存在多态性的情况下指向指针很困难。

答案 1 :(得分:1)

EnumMap<MyEnum, String>EnumMap<? extends MyInterface, String>是不同的类型(前者是后者的子类型)。因此List<EnumMap<MyEnum, String>>List<EnumMap<? extends MyInterface, String>>彼此不兼容。通常,如果A和B是不同的类型,则无法将List<A>分配给List<B>,无论A和B之间的关系是什么(同样适用于任何泛型类型而不仅仅是List)。当你有一个有界类型参数时,这是一个不同的故事;兼容性需要考虑范围。