带有泛型的 Java 集合给我不适用的参数错误

Ben*_*ynn 5 java generics

我有一个FourByFourBoard扩展的类GameBoard。我定义了以下字段:

private Map<Integer,List<Key<? extends GameBoard>>> mGameTypeToKeysMap = new Hashtable<Integer,List<Key<? extends GameBoard>>>();

private List<Key<FourByFourBoard>> mFourByFourBoardKeys = new ArrayList<Key<FourByFourBoard>>();
Run Code Online (Sandbox Code Playgroud)

在我的构造函数中,我尝试调用:

mGameTypeToKeysMap.put(Game.FOUR_BY_FOUR, mFourByFourBoardKeys);
Run Code Online (Sandbox Code Playgroud)

但我明白了:

put(Integer, List<Key<? extends GameBoard>>)类型中的 方法Map<Integer,List<Key<? extends GameBoard>>>不适用于参数(int, List<Key<FourByFourBoard>>)

我可以使用不同的方法来完成我想做的事情,但是在盯着代码一段时间后,我不太明白为什么这不起作用。

编辑

这个问题可能比我想象的要简单:

如果我尝试:

Key<GameBoard> a = mFourByFourBoardKeys.get(0);
Run Code Online (Sandbox Code Playgroud)

我得到:

类型不匹配:无法从 转换Key<FourByFourBoard>Key<GameBoard>

虽然:

GameBoard someBoard = new FourByFourBoard();
Run Code Online (Sandbox Code Playgroud)

是合法的。所以这仍然是一个泛型问题,但集合部分并不重要。我的头仍然有点旋转。

Rob*_*bin 3

AList<A extends B>和 aList<B>不同,因为对于第一个列表,您只能添加A实例,而对于第二个列表,您可以添加 和A实例B

\n\n

Java 泛型教程中对此进行了很好的解释,更具体地说,在第 4 页(泛型和子类型部分)

\n\n

编辑

\n\n

一个小例子说明了这一点并更紧密地匹配您的代码

\n\n
Map<Integer, List<List<? extends Number>>> a = new Hashtable<Integer,List<List<? extends Number>>>();\nList<List<Double>> b = new ArrayList<List<Double>>();\na.put(0, b);//won\'t compile\nList<List<? extends Number>> c = new ArrayList<List<? extends Number>>(  );\na.put( 1, c );//works perfectly\n
Run Code Online (Sandbox Code Playgroud)\n\n

我链接的 PDF 中解释了无法编译的原因,并引用了相关部分

\n\n
\n

让\xe2\x80\x99s 测试一下我们对泛型的理解。下面的代码片段合法吗?

\n
\n\n
List<String> ls = new ArrayList<String>(); //1\nList<Object> lo = ls; //2\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n

1号线当然是合法的。问题的棘手部分是第 2 行。这可以归结为问题:字符串列表是对象列表吗?大多数人\xe2\x80\x99的本能反应是:\n\xe2\x80\x9csure!\xe2\x80\x9d。\n好吧,看看接下来的几行:

\n
\n\n
lo.add(new Object()); // 3\nString s = ls.get(0); // 4: attempts to assign an Object to a String\n
Run Code Online (Sandbox Code Playgroud)\n\n

我建议通读整个 PDF,并查看该文档中的(其他)示例。

\n