首页 > 解决方案 > 如何使以下分配合法化?

问题描述

以下产生了 ClassCastException,我无法确定原因。我知道泛型数组有点禁忌,因为它具有不变性与协变性属性,并且泛型不是可重构的,但不明白为什么会生成 RuntimeException。

   ...
   Integer[] sap = (Integer[]) iterableToArray(path.pathTo(w));
}

private <T> T[] iterableToArray(Iterable<T> it){
   ArrayList<T> list = new ArrayList<>();
   for(T o : it)
      list.add(o);
   return (T[]) list.toArray();

}

标签: javaarraysgenericsjava-8

解决方案


你可以这样做:

private static <T> T[] iterableToArray(Iterable<T> it, T[] arrayTemplate){
  ArrayList<T> list = new ArrayList<>();
  for(T o : it)
    list.add(o);
  return list.toArray(arrayTemplate);
}

并这样称呼它:

Integer[] sap = iterableToArray(path.pathTo(w), new Integer[0]);

您必须传递一个具有具体类型的变量 for T,因为该方法iterableToArray需要一个来创建数组。您不需要转换 的结果iterableToArray,因此这种用法是类型安全的。

该变量arrayTemplate仅用于将类型传递给方法。由于结果不适合大小为 0 的数组,因此该方法toArray创建了一个新数组。这通常比将所需大小的数组传递给方法要快toArray。而且它也更简单。所以这是首选的方法。


推荐阅读