The toArray
method (lets pick the implementation in java.util.ArrayList) is the following:
class ArrayList ....{
public T
I think John B's answer covered the idea well - I'd just like to elaborate on it a little.
First, let's look at the method signature you proposed in your question:
public E[] toArray(E[] a)
As John explained, this signature is less flexible. If I want to dump an ArrayList
into a Number[]
, this method doesn't let me. The Collections API wants to allow that flexibility.
Unfortunately the method as it stands doesn't allow for compile-time checking on the type of the array, which is the issue you seem to be getting at. The documentation for toArray, which is declared by the Collection
, explains that an ArrayStoreException
may be thrown "if the runtime type of the specified array is not a supertype of the runtime type of every element in this collection".
Based on that description, it seems like the following signature would be ideal:
public T[] toArray(T[] a)
At first glance, this seems like it would allow any legal type of array to be passed in and populated - but would provide type checking at compile time instead of run time. So why is this signature not declared instead?
Well, this syntax:
is not supported by the language. But it's easy for that to distract you from the fact that this type checking wouldn't work anyway. The problem is that unlike parameterized types, arrays are covariant. An Integer[]
is a Number[]
is an Object[]
. So given our hypothetical signature with
, if I called toArray
on an ArrayList
and passed in an Integer[]
, it would still compile - and possibly fail at runtime depending on what was in the list.
So the bottom line is, a lower bound on the component type of the array passed in isn't going to do any good.