I was just looking at the method defined in the List interface: <T> T[] toArray(T[] a)
, and I have a question. Why is it generic? Because of that fact, method is not complete type-safe. The following code fragment compiles but causes ArrayStoreException:
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
String[] stringArray = list.toArray(new String[]{});
It seems to me if toArray was not generic and took List type parameter, it would be better.
I have written toy example and it is ok witout generic:
package test;
import java.util.Arrays;
public class TestGenerics<E> {
private Object[] elementData = new Object[10];
private int size = 0;
public void add(E e) {
elementData[size++] = e;
}
@SuppressWarnings("unchecked")
//I took this code from ArrayList but it is not generic
public E[] toArray(E[] a) {
if (a.length < size)
// Make a new array of a's runtime type, but my contents:
return (E[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
public static void main(String[] args) {
TestGenerics<Integer> list = new TestGenerics<Integer>();
list.add(1);
list.add(2);
list.add(3);
//You don't have to do any casting
Integer[] n = new Integer[10];
n = list.toArray(n);
}
}
Is there any reason why it is declared that way?
a. It serves as a type token, telling the method what type of array to create. It's up to you to pass the correct type there. Otherwise the only thing the method could return is anObject[].Listinstance has no idea what its item type is, so doing so automatically is impossible.Listbeforehand. The compiler can statically prove the code is type safe for those.