将Iterable 转换为T 的可重用方法?

我正在尝试编写一个generics方法来返回数组forms的Iterable的内容。

这是我有的:

public class IterableHelp { public  T[] toArray(Iterable elements) { ArrayList arrayElements = new ArrayList(); for(T element : elements) { arrayElements.add(element); } return (T[])arrayElements.toArray(); } } 

但我收到编译器警告’注意:… \ IterableHelp.java使用未经检查或不安全的操作。

有关另一种避免这种警告的方法的想法吗?

Google Guava中有一种方法Iterables.toArray

查看源代码 ,定义为:

  /** * Copies an iterable's elements into an array. * * @param iterable the iterable to copy * @param type the type of the elements * @return a newly-allocated array into which all the elements of the iterable * have been copied */ public static  T[] toArray(Iterable iterable, Class type) { Collection collection = toCollection(iterable); T[] array = ObjectArrays.newArray(type, collection.size()); return collection.toArray(array); } 

ObjectArrays.newArray最终委托给一个看起来像这样的方法:

  /** * Returns a new array of the given length with the specified component type. * * @param type the component type * @param length the length of the new array */ @SuppressWarnings("unchecked") static  T[] newArray(Class type, int length) { return (T[]) Array.newInstance(type, length); } 

所以看起来没有办法完全避免@SuppressWarnings ,但你可以而且至少应该将它限制在尽可能小的范围内。

或者,更好的是,只需使用其他人的实现!

没有办法摆脱unchecked or unsafe operations警告,或创建TypeSafe数组而不编辑方法签名。

有关详细信息,请参阅此错误报告 。

一种方法是传入预先分配的Type T数组:

 public class IterableHelp { public  T[] toArray(final T[] t, final Iterable elements) { int i = 0; for (final T element : elements) { t[i] = element; } return t; } } 

这摆脱了unchecked or unsafe警告,但它也将责任放在调用类上,以创建具有正确边界的数组,以便以哪种方式破坏了方便方法的目的。

如果要动态创建TypeSafe数组,实际上无法在Java中以TypeSafe方式执行此操作。

这可以工作和编译,但它不能解决未经检查或不安全强制转换问题,它只是将它移动到另一个地方。 我必须添加@SuppressWarnings注释才能让它停止抱怨演员。

 @SuppressWarnings({"unchecked"}) public class IterableHelp { public  T[] toArray(Class t, Iterable elements) { final ArrayList arrayElements = new ArrayList(); for (T element : elements) { arrayElements.add(element); } final T[] ta = (T[]) Array.newInstance(t, arrayElements.size()); return arrayElements.toArray(ta); } } 

你遇到了比未经检查的警告更大的问题。 实际上,如果T不是Object,它将在运行时抛出ClassCastException。

Try String[] foo = IterableHelp.toArray(new ArrayList());

简单地说,由于数组在运行时包含组件类型,因此要创建正确的T [],必须将组件类作为另一个参数传入(作为T或T []本身的类,或作为T或T的对象[]),并使用reflection来创建数组。 CollectiontoArray()方法采用参数的forms,因此接受T []对象。