我遇到了一些我发现在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>
。有人可以解释吗? 最佳答案
这是因为存在从List<String>
到List<? extends Object>
的隐式转换,而不是从Map<Long, List<String>>
到Map<Long, List<? extends Object>>
的隐式转换。
除非您使用通配符类型,否则所有通用类型都是不变的。由于“外部” Map类型的泛型类型参数中没有通配符,因此它无法捕获任何不完全匹配的泛型类型。
如果您的 map 类型是Map<Long, ? extends List<? extends Object>>
,那么它将按照您的期望工作。
如果答案是子类可以覆盖或实现具有不同返回类型的父类(super class)型方法,则只有另一部分,但前提是子类型的方法的返回类型可以隐式转换为父类(super class)型方法的返回类型。 (在Java 1.4及更低版本中,即使这样也不起作用:如果类型不完全匹配,则将是编译时错误。)