I have a class FourByFourBoard that extends GameBoard. I define the following fields:
private Map<Integer,List<Key<? extends GameBoard>>> mGameTypeToKeysMap = new Hashtable<Integer,List<Key<? extends GameBoard>>>();
private List<Key<FourByFourBoard>> mFourByFourBoardKeys = new ArrayList<Key<FourByFourBoard>>();
In my constructor, I try to call:
mGameTypeToKeysMap.put(Game.FOUR_BY_FOUR, mFourByFourBoardKeys);
But I get this:
The method
put(Integer, List<Key<? extends GameBoard>>)in the type
Map<Integer,List<Key<? extends GameBoard>>>is not applicable for the
arguments(int, List<Key<FourByFourBoard>>)
I can use a different approach to do what I’m trying to do, but after staring at the code for a little while I can’t quite figure out why this doesn’t work.
EDIT
This problem might be simpler than I thought:
If I try:
Key<GameBoard> a = mFourByFourBoardKeys.get(0);
I get:
Type mismatch: cannot convert from
Key<FourByFourBoard>to
Key<GameBoard>
Even though:
GameBoard someBoard = new FourByFourBoard();
Is legal. So this is still a generics question, but the collections part was not important. And my head is still spinning a little.
A
List<A extends B>and aList<B>are not the same, since to the first list you can only addAinstances, and to the second you can add bothAandBinstances.This is all perfectly well explained in the Java generics tutorial, more specifically on page 4 (Section Generics and Subtyping)
Edit
A small example illustrating this and matching your code a bit more closely
The reason why this not compiles is explained in that PDF to which I linked, and to quote the relevant part
I suggest to go through that whole PDF, and take a look at the (other) examples in that document.