泛型和抽象方法

luc*_*svw 8 java generics

我遇到过一些我在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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编译器在getMap()方法上显示错误:

getMap() in ConcreteClass cannot override getMap() in AbstractClass
  return type Map<Long, List<String>> is not compatible with Map<Long, List<? extends Object>>
Run Code Online (Sandbox Code Playgroud)

但是该getList()方法不存在相同的错误,但我希望两者都可以工作,或者两者都失败.在这两种情况下,最重要的方法都是List<String>代替List<? extends Object>.有人可以解释一下吗?

Dan*_*den 10

这是因为存在从一个隐式转换List<String>List<? extends Object>,但不能从Map<Long, List<String>>Map<Long, List<? extends Object>>.

除非您使用通配符类型,否则所有泛型类型都是不变的.由于"外部"Map类型的泛型类型参数中没有通配符,因此它无法捕获任何不完全匹配的泛型类型.

如果你的地图类型是Map<Long, ? extends List<? extends Object>>那么它会像你期望的那样工作.

而另一部分如果回答是,子类可以覆盖或实现具有不同的返回类型的超类型的方法,但只有当亚型的方法的返回类型是隐式转换为超类方法的返回类型.(在Java 1.4及更低版本中,即使这样也行不通:如果类型不完全匹配,那将是编译时错误.)

  • 好的一点,我想补充一点?extends``可以替换为`?`而没有任何影响 (3认同)
  • @Andrew:当然,但同样的原则适用于通配符的任何下限,而不仅仅是`Object`. (2认同)