I expected that any type can be used instead of wildcard (?).
It is true with extends (as I expected), but it is a compile error with super (I don't understand why it is different from extends example).
How shall I think about this difference - is this a bug or a feature?
class Why {
void fSuper(List<? super Map<String,?>> lst) { }
void fExtends(List<? extends Map<String,?>> lst) { }
void test(){
// Why any type instead of ? gives error
fSuper(new ArrayList<Map<String, String>>()); // compile ERR - WHY ???
fSuper(new ArrayList<Map<String, Byte>>()); // c. ERR - WHY ???
fSuper(new ArrayList<Map<String, Map<Short, Boolean>>>()); // c. ERR - WHY ???
fSuper(new ArrayList<Map<String,?>>()); // OK
// Any type instead of ? can be used OK
fExtends(new ArrayList<Map<String, String>>()); // OK
fExtends(new ArrayList<Map<String, Byte>>()); // OK
fExtends(new ArrayList<Map<String, Map<Short, Boolean>>>()); // OK
fExtends(new ArrayList<Map<String,?>>()); // OK
This question was inspired by example in answer of pdem here
His example seems very inconsistent with my IDE
void populateList(List<? super Map<String,?>> list) {
list.clear();
Map<String, String> map;
map = new HashMap<String,String>();
map.put("key", "value"); // compiles
// Map<String, String> for List<? super Map<String,?>>
list.add(map); // compiles !!
}
P.S. I understand PECS (Producer extends / Consumer super). (Please don't close the question for that reason). But I don't see how to use it in my first code snippet. I think I fully understand the second code snippet. But I don't understand why ArrayList<Map<String, String>>
does not compile in my first code snippet (with ...? super) and does compile in the second code snippet and does compile in my first code snippet (with ...? extends).
I also realize that using wildcards (?) is often a way to trouble (especially if violating PECS prescriptions).
But I want to deeply understand generics, and the first code snippet beats my understanding so far.