Why is toArray() a Generic Method in Java Collections?
Here’s something that caught my eye in the Java Collections API:
<T> T[] toArray(T[] a)The collection is already parameterized — List<E>, Set<E>, etc. So why does toArray need to declare its own type parameter T? Why isn’t it just:
E[] toArray(E[] a)I wrote a simple AList<E> generic class to experiment:
public class AList<E> {
private Object[] elements;
private int size;
public <T> T[] toArray(T[] a) {
System.arraycopy(elements, 0, a, 0, size);
return a;
}
}Both the pre-Java 5 untyped version and the Java 5 generic version worked in my tests. But that didn’t answer the underlying question — why the extra type parameter?
The answer involves some interesting subtleties about Java’s type system, supertype bounds, and the PECS principle. I posted the question to CinJUG and got some great responses — I’ll write up the full explanation in a follow-up post.
Teaser: it has to do with allowing callers to pass in an array of a supertype of the collection’s element type, which turns out to be genuinely useful in practice.
See the answer post for the full breakdown.