从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 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 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 obj = (List) new ArrayList(); 

我希望这个问题很明显。 子类型列表不能转换为超类型列表。

除了已发布的答案,请查看以下内容

  • 什么-是最意义的最类型安全预警function于某些-Java的generics类型转换
  • 困惑按Java的generics需要再次一铸

编译器会生成警告,此类型中的元素将在稍后的代码中访问,而不是先前定义的generics类型。 此外,运行时的类型信息也不可用。