Class definition
public interface ITest {
Long foo();
}
public class Test implements ITest{
@Override
public Long foo() {
return 0L;
}
}
Methods
public Map<Long, List<? extends ITest>> moo() {
List<Test> a = List.of(new Test());
Map<Long, List<? extends ITest>> b = Map.of(1L, a);
return b;
}
public Map<Long, List<? extends ITest>> koo() {
List<Test> a = List.of(new Test());
Map<Long, List<Test>> b = Map.of(1L, a);
return b;
}
public List<? extends ITest> too() {
List<Test> a = List.of(new Test());
return a;
}
I get an error only at the koo()
function. Why does this not work? Does the List class that is wrapped by the Map class not support generics?
Below is the error I get.
Incompatible types. Found: 'java.util.Map<java.lang.Long,java.util.List<Test>>', required: 'java.util.Map<java.lang.Long,java.util.List<? extends ITest>>'
I think it should work properly, but it didn't.
Your too
method compiles because a List<Test>
is a subtype of the declared return type of the method, List<? extends ITest>
. Your explicit ? extends
in the return type makes List<Test>
a subtype.
Your koo
method does not compile because even though List<Test>
is a subtype of List<? extends ITest>
, a Map<Long, List<Test>>
is not a subtype of Map<Long, List<? extends ITest>>
. Nesting that generics relationship in another generic type is not allowed, because you're using invariant generics.
If you removed ? extends
from the return type of too
, then that method wouldn't compile because List<Test>
is not a subtype of List<ITest>
.
Like what is needed for too
, add ? extends
to the return type for koo
to get this to compile. The type Map<Long, List<Test>>
is a subtype of Map<Long, ? extends List<? extends ITest>>
because of this added ? extends
.
// vvvvvvvvv
public Map<Long, ? extends List<? extends ITest>> koo() {