The following code compiles but if I uncomment the commented line, it does not and I am confused why. HashMap does extend AbstractMap and the first line where map is declared compiles fine.
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String args[]) {
Map<String, ? extends AbstractMap<String, String>> map = new HashMap<String, HashMap<String, String>>();
//map.put("one", new HashMap<String, String>());
}
}
And, I know the “right way” is this:
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String args[]) {
Map<String, Map<String, String>> map = new HashMap<String, Map<String, String>>();
map.put("one", new HashMap<String, String>());
}
}
The first code is unsafe – imagine you’re actually written:
Now:
We should have a
ConcurrentHashMap– but in reality we’ve only got aHashMap.This is actually a lot simpler to explain if we reduce the amount of generics going on… your scenario is really equivalent to (say):
which looks okay, until you consider that it’s equivalent in validity (as far as the compiler is concerned) to:
which is obviously not okay. The compiler has to treat the two in the same way, so it makes both of them invalid.