java - 通用返回类型 - 为什么我不能这样做?

标签 java generics inheritance return-type

考虑下面的片段。我了解覆盖对于泛型类型的工作方式,以及返回类型 List<String> 的原因(例如)被允许覆盖 List<? extends Object> .但是,我不完全清楚为什么像 1 和 2 这样的语句无法编译...继承不应该也适用于此吗?

public class Generics {

    public static void main(String[] args) {

        A instance = new B();
        X instance2 = new Y();

        Map<String, String> map = instance2.getMap(); // 1
        List<String> list = instance.getList();       // 2
    }
}

class A {

    List<? extends Object> getList() {

        return null;
    }
}

class B
        extends A {

    List<String> getList() {

        return new LinkedList<String>();
    }
}

class X {

    Map<String, ? extends Object> getMap() {

        return null;
    }
}

class Y
        extends X {

    @Override
    Map<String, String> getMap() {

        return null;
    }
}

最佳答案

Map<String, String> map = instance2.getMap(); // 1

编译器看到对 X.getMap() 的调用它的返回类型为 Map<String, ? extends Object> .这不能转换为 Map<String, String> . instance2没关系类型为 Y在运行时;这是失败的纯编译时静态类型检查。

List<String> list = instance.getList();       // 2

同样的推理也适用。 instance 的编译时类型是A , 和 A.getList()返回 List<? extends Object>这与 List<String> 不兼容.

请注意,这不是泛型特有的问题。出于同样的原因,这也将无法编译:

class A { Object getObject(); }
class B extends A { String getObject(); }

A a = new B();
String s = a.getObject();

如果你想让它工作,那么你需要给编译器一些额外的帮助。通过转换为子类:

String s = ((B) a).getObject();

或者通过转换返回值:

String s = (String) a.getObject();

关于java - 通用返回类型 - 为什么我不能这样做?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13591551/

相关文章:

Java仅返回父类(super class)的属性

javascript - Paperjs 0.9.25 - item.setRampPoint 不是函数

java - 神经网络应该学习多少个 epoch? (包括测试结果)

java - 我自己的Java编译器和字节码: Problems invoking functions

c# - 将泛型结构转换为具有不同类型参数的相同泛型结构

go - 检查不同 Go Map 类型中的重复键

java - 使用 thymeleaf 和比较的嵌套循环

c# - 检查 int、string、double 等任何类型的 null 或 empty 的通用方法

python - 如何覆盖两层深度的类属性?

wpf 用户控件基类问题