A DESCRIPTION OF THE REQUEST :
java.util.Collection defines method <T> T[] toArray(T[] a);
Unfortunately, this is not compile-time type-safe, which can be seen in the test case below. The problem is that the signature of the method doesn't refer to the type parameter <E> of Collection.
The correct signature of toArray(..) would be something like this, but this is not valid in Java: <T super E> T[] toArray(T[] a);
Since I don't think Collection#toArray(T[]) can be fixed, I suggest a type-safe helper method in the java.util.Collections class:
/**
* Returns an array containing all of the elements in the given collection. This is a
* compile-time type-safe alternative to {@link Collection#toArray(Object[])}.
*
* @param collection the source collection
* @param clazz the type of the array elements
* @param <A> the type of the array elements
* @return an array of type <code>A</code> containing all of the elements in the given
* collection
* @throws NullPointerException if the specified collection or class is null
*/
public static <A> A[] toArray(Collection<? extends A> collection, Class<A> clazz) {
Object array= Array.newInstance(clazz, collection.size());
@SuppressWarnings("unchecked")
A[] typedArray= collection.toArray((A[]) array);
return typedArray;
}
JUSTIFICATION :
1.6 code like this compiles fine but throws an ArrayStoreException at run time:
Integer[] ints = nums.toArray(new Integer[nums.size()]);
With the suggested method, clients see the type safety problem at compile time:
Integer[] ints = Collections2.toArray(nums, Integer.class);
An added benefit of the new method is that the client doesn't have to write boilerplate code to create an array of a specific type.
---------- BEGIN SOURCE ----------
import java.util.*;
public class ArrayTypeBreak {
public static void main(String[] args) {
Collection<Number> nums = new ArrayList<Number>();
nums.add(new Integer(1));
nums.add(new Long(-1));
Object[] objs = nums.toArray(new Object[0]);
Object[] objs2 = nums.toArray(new Number[0]);
Number[] nums2 = nums.toArray(new Number[0]);
// No compile-time warning, but throws ArrayStoreException:
Integer[] ints = nums.toArray(new Integer[nums.size()]);
for (Integer integer : ints) {
System.out.println(integer);
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Clients can use a home-made helper method. However, such basic functionality should be shared in the JRE.