Reputation: 2382
Short, self contained, non-compilable example:
public void test1() throws Exception {
Map<String, Map<String, Set<String>>> a = Collections.singletonMap("One",
Collections.singletonMap("Two", new HashSet<String>()));
foo(a);
}
void foo(Map<String, Map<String, ? extends Collection<String>>> x) {
}
Yields (javac 1.8.0_102):
error: incompatible types: Map<String,Map<String,Set<String>>> cannot be converted to Map<String,Map<String,? extends Collection<String>>>
foo(a);
^
I expect foo
to take any subtype of Collection
like Set
or List
. What is wrong with code above?
Upvotes: 2
Views: 200
Reputation: 30335
Your code doesn't compile for the same reason the following (simpler) code doesn't compile:
List<Integer> l = Arrays.asList(1,2,3);
foo(l); //The method v(List<Object>) in the type Test is not applicable for the arguments (List<Integer>)
public void foo (List<Object> a){
...
}
The fact that Integer
extends Object
doesn't mean that List<Integer>
extends List<Object>
. They're two different, unrelated, types.
We can fix the compilation error in the simple case by changing foo
's signature to:
public void foo (List<? extends Object> a){
...
}
This tells the compiler that foo
will be accepting a List of something that extends Object, which is what List<Integer>
is.
In your case, Map<String, Map<String, Set<String>>>
doesn't extend Map<String, Map<String, ? extends Collection<String>>>
.
Even if you changed your foo
to void foo(Map<String, Object> x)
it wouldn't compile since Map<String, Map<String, Set<String>>>
does not extend Map<String, Object>
. They're two different types.
To get it to work, you can change foo
's signature to void foo(Map<String, ? extends Map<String, ? extends Collection<String>>> x)
Upvotes: 3
Reputation: 2789
The way you declared foo, the compiler demands a type parameter of the exact type Map<String, ? extends Collection<String>>
. You could make foo generic:
<C extends Collection<String>> void foo(Map<String, Map<String, C>> x) {
}
Upvotes: 3
Reputation: 4399
This compiles
void foo(Map<String, ? extends Map<String, ? extends Collection<String>>> x)
Upvotes: 2