将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 extends T> iterable, Class type) { Collection extends T> 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来创建数组。 Collection
的toArray()
方法采用参数的forms,因此接受T []对象。