3

考虑下面的片段。我了解关于泛型类型的覆盖是如何工作的,以及为什么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;
    }
}
4

3 回答 3

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

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

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

同样的道理也适用。的编译时类型instanceA,并A.getList()返回List<? extends Object>与 不兼容的a 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();
于 2012-11-27T19:30:05.060 回答
1

多态性不能向后工作。

如果您尝试使用扩展的不同类X,但它返回给您一个\

Map<String, NonString>

反而?

于 2012-11-27T19:28:46.553 回答
0

您正在调用getMapX因为instance2是通过 推荐人X),它被定义为返回Map<String, ? extends Object>因此问题。

如果您将呼叫更改为(类型转换instance2Ybefore call getMap()):

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

它应该可以工作,因为您instance2的仍然是 type Y

于 2012-11-27T19:36:00.107 回答