I met one puzzle about java generics which I never met before and post out here, hope you could have one check at it. Here the whole code:
public class FakeTester
{
public static void main(String[] args)
{
List<FakeConcretClassA> concretFakes = new ArrayList<>();
concretFakes.add(new FakeConcretClassA());
Map<String, List<FakeConcretClassA>> fakemap = new HashMap<>();
fakemap.put("key1", concretFakes);
printFakeVals(concretFakes);
priFakeMap(fakemap);
}
public static void priFakeMap(Map<String, List<? extends FakeInterface>>
fakemap)
{
fakemap.forEach((genre, fakes) -> {
fakes.forEach(fake -> System.out.println(fake.fakeVal()));
});
}
public static void printFakeVals(List<? extends FakeInterface> fakes)
{
fakes.forEach(fake -> System.out.println(fake.fakeVal()));;
}
}
The FakeInterface is just one simple interface which requires one method that return hardcoded value, and FakeConcretClassA return '111' for implementation. What is strange here is that the printFakeVals(concretFakes); could pass java compile but the priFakeMap(fakemap); could not. Per my understanding, FakeConcretClassA implements FakeInterface so I could pass list of FakeConcretClassA as param to method which receives list of objs which implements FakeInterface. But why when wrapped into the map and the compile would fail?