从List 扩展为Java中的List 类型的列表?
我认为标题应该解释所有,但以防万一……
我想知道以下Java代码片段可能产生与转换相关的风险和潜在问题:
List wildcardList = someAPI.getList(); List typedList = (List) wildcardList;
我的想法是wildcardList中的所有对象都应该是MyObject的实例(精确类型或子类),因此每当从typedList检索对象时,就不应该有ClassCastException。 它是否正确? 如果是这样,为什么编译器会生成警告?
只要您从列表中检索对象就应该没有问题。 但是,如果您在其上调用其他方法,则可能会导致运行时exception,如下面的代码所示:
List intList = new ArrayList (); intList.add(2); List extends Number> numList = intList; List strictNumList = (List ) numList; strictNumList.add(3.5f); int num = intList.get(1); //java.lang.ClassCastException: java.lang.Float cannot be cast to java.lang.Integer
你是否正确从typedList检索对象,这应该工作。
问题是您稍后向typedList添加更多对象。 例如,如果MyObject有两个子类A和B,而wildcardList的类型为A,那么就不能向它添加B。 但由于typedList属于父类型MyObject,因此只会在运行时捕获此错误。
考虑你做的事情如下:
List childClassList = new ArrayList (); 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 List typedList = (List ) 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
我希望这个问题很明显。 子类型列表不能转换为超类型列表。
除了已发布的答案,请查看以下内容
- 什么-是最意义的最类型安全预警function于某些-Java的generics类型转换
- 困惑按Java的generics需要再次一铸
编译器会生成警告,此类型中的元素将在稍后的代码中访问,而不是先前定义的generics类型。 此外,运行时的类型信息也不可用。