如何使下面的赋值合法?

问题描述 投票:0回答:1

下面产生一个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();

}
java generics
1个回答
2
投票

你可以这样做。

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]);

你必须给一个变量传递一个重新定义的类型,用于 T因为该方法 iterableToArray 需要一个数组来创建。你不需要将 iterableToArray所以这种用法是类型安全的。

变量 arrayTemplate 仅用于将类型传递给方法。由于结果不适合放在大小为0的数组中,所以方法 toArray 制作一个新的数组。这通常比将一个所需大小的数组传递给方法 toArray. 而且也比较简单。所以这是首选的方式。


0
投票

如果iterable是整数的iterable,而且你使用的是java 8+,那么你可以用这个方法来实现

Iterable<Integer> iterable = Arrays.asList(5, 7, 11, 13, 17);
Integer[] numbers = StreamSupport.stream(iterable.spliterator(), false).toArray(Integer[]::new);

0
投票

你不能投 Object[]Integer[].

只要你不能实例化一个通用类型数组(new T[]),您必须提供 IntFunction<T[]> generator 生成一个新的数组,该数组具有所需类型和提供的长度。参见 爪哇.

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

.应简化为.。

static <T> T[] iterableToArray(Iterable<T> it, IntFunction<T[]> toArrayFunction) {
    return StreamSupport.stream(it.spliterator(), false).toArray(toArrayFunction);
}

使用方法引用的用法相当简单。

Integer[] sap = (Integer[]) iterableToArray(path.pathTo(w), Integer[]::new);
© www.soinside.com 2019 - 2024. All rights reserved.