我遇到了一些我发现在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及更低版本中,即使这样也不起作用:如果类型不完全匹配,则将是编译时错误。)

10-07 13:14
查看更多