Java 从list<;类型的列表显式强制转换有哪些风险;?扩展MyObject>;到类型列表的列表<;MyObject>;在爪哇?
我认为标题应该解释一切,只是以防万一 我想知道以下Java代码片段可能会带来哪些与强制转换相关的风险和潜在问题:Java 从list<;类型的列表显式强制转换有哪些风险;?扩展MyObject>;到类型列表的列表<;MyObject>;在爪哇?,java,generics,Java,Generics,我认为标题应该解释一切,只是以防万一 我想知道以下Java代码片段可能会带来哪些与强制转换相关的风险和潜在问题: List<? extends MyObject> wildcardList = someAPI.getList(); List<MyObject> typedList = (List<MyObject>) wildcardList; List关于从typedList检索对象,您是正确的,这应该可以工作 问题是以后向typedList添加更多对象时
List<? extends MyObject> wildcardList = someAPI.getList();
List<MyObject> typedList = (List<MyObject>) wildcardList;
List关于从typedList检索对象,您是正确的,这应该可以工作
问题是以后向typedList添加更多对象时。例如,如果MyObject有两个子类A和B,并且通配符列表的类型为A,则不能向其中添加B。但由于typedList属于父类型MyObject,因此仅在运行时才会捕获此错误。这与
List<Object> obj = (List<Object>) new ArrayList<String>();
List obj=(List)new ArrayList();
我希望问题是显而易见的。子类型列表不能强制转换为超类型列表 只要从列表中检索对象,就应该没有问题。但是,如果对其调用其他一些方法(如以下代码所示),则可能会导致运行时异常:
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
List intList=new ArrayList();
增加(2);
列出考虑你做的事情如下:
List<ChildClassOne> childClassList = new ArrayList<ChildClassOne>();
childClassList.add(childClassOneInstanceOne);
childClassList.add(childClassOneInstanceTwo);
List<? extends MyObject> wildcardList = childClasslist; // works fine - imagine that you get this from a method that only returns List<ChildClassOne>
List<MyObject> typedList = (List<MyObject>) wildcardList; // warning
typedList.add(childClassTwoInstanceOne); // oops my childClassList now contains a childClassTwo instance
ChildClassOne a = childClassList.get(2); // ClassCastException - can't cast ChildClassTwo to ChildClassOne
List childClassList=new ArrayList();
添加(childClassOneInstanceOne);
添加(childClassOneInstanceTwo);
列表除了已经发布的答案,还可以查看以下内容
如果稍后在代码中访问该类型中的元素,并且该元素不是以前定义的泛型类型,编译器将生成警告。运行时的类型信息也不可用。这甚至无法编译。但是OP正在执行的操作将编译,但可能在运行时失败。是的,这是正确的。但我只是想证明有一些根本错误。+1,很好的例子。然而,值得指出的是,只要您只调用“get”类型的操作,您甚至不需要/受益于强制转换。您需要强制转换的唯一时间是,如果您想执行“不安全”的操作(调用库方法时可能会出现例外,这些库方法在使用泛型参数时不够灵活)。