从List <?列表中明确转换的风险是什么?将MyObject>扩展为Java中List <MyObject>类型的列表?

ste*_*bot 7 java generics

我认为标题应该解释一下,但以防万一......

我想知道以下Java代码片段可能产生与转换相关的风险和潜在问题:

List<? extends MyObject> wildcardList = someAPI.getList();
List<MyObject> typedList = (List<MyObject>) wildcardList;
Run Code Online (Sandbox Code Playgroud)

我的想法是wildcardList中的所有对象都应该是MyObject的实例(确切的类型或子类),因此每当从typedList检索对象时,就不应该有ClassCastException.它是否正确?如果是这样,为什么编译器会生成警告?

Mar*_*amy 7

只要您从列表中检索对象就应该没有问题.但是,如果您在其上调用其他方法,则可能会导致运行时异常,如下面的代码所示:

    List<Integer> intList = new ArrayList<Integer>();
    intList.add(2);

    List<? extends Number> numList = intList;
    List<Number> strictNumList = (List<Number>) numList;
    strictNumList.add(3.5f);

    int num = intList.get(1); //java.lang.ClassCastException: java.lang.Float cannot be cast to java.lang.Integer
Run Code Online (Sandbox Code Playgroud)


Tho*_*ler 2

您关于从 typedList 检索对象的说法是正确的,这应该可行。

问题是当您稍后向 typedList 添加更多对象时。例如,如果 MyObject 有两个子类 A 和 B,而 wildcardList 的类型为 A,则不能向其中添加 B。但由于 typedList 是 MyObject 的父类型,因此该错误只会在运行时捕获。