我遇到了一些我在Java中发现奇怪的东西并且无法找到有关它的更多信息。请考虑以下代码:
public class TestClass {
private static abstract class AbstractClass {
abstract List<? extends Object> getList();
abstract Map<Long, List<? extends Object>> getMap();
}
private static final class ConcreteClass extends AbstractClass {
@Override
List<String> getList() {
return null;
}
@Override
Map<Long, List<String>> getMap() {
return null;
}
}
}
编译器在getMap()
方法上显示错误:
getMap() in ConcreteClass cannot override getMap() in AbstractClass
return type Map<Long, List<String>> is not compatible with Map<Long, List<? extends Object>>
但getList()
方法不存在同样的错误,但我希望两者都可以工作,或者两者都失败。在这两种情况下,最重要的方法是List<String>
来代替List<? extends Object>
。有人可以解释一下吗?
答案 0 :(得分:10)
这是因为存在从List<String>
到List<? extends Object>
的隐式转换,但不是从Map<Long, List<String>>
到Map<Long, List<? extends Object>>
。
除非您使用通配符类型,否则所有泛型类型都是不变的。由于&#34;外部&#34;没有通配符。映射类型的泛型类型参数,它无法捕获任何不完全匹配的泛型类型。
如果您的地图类型为Map<Long, ? extends List<? extends Object>>
,那么它会像您期望的那样工作。
另一部分如果答案是子类可以覆盖或实现具有不同返回类型的超类型方法,但前提是子类型方法的返回类型可以隐式转换为超类型方法&#39; s返回类型。 (在Java 1.4及更低版本中,即使不起作用:如果类型并不完全匹配,那将是一个编译时错误。)