I was just looking at the method defined in the List interface:
Returns an array containing all of the elements in this list in the correct order; the runtime type of the returned array is that of the specified array. If the list fits in the specified array, it is returned therein. Otherwise, a new array is allocated with the runtime type of the specified array and the size of this list. If the list fits in the specified array with room to spare (i.e., the array has more elements than the list), the element in the array immediately following the end of the collection is set to null. This is useful in determining the length of the list only if the caller knows that the list does not contain any null elements.
<T> T[] toArray(T[] a);
And I was just wondering why is it implemented this way, basically if you pass it an array with a length < to the list.size(), it will simply create a new one and return it. Therefore the creation of the new Array Object in the method parameter is useless.
Additionally if you pass it an array long enough using the size of the list if returns that same object with the objects - really no point in returning it since it is the same object but ok for clarity.
The problem is that I think this promotes slightly inefficient code, in my opinion toArray should simply receive the class and just return the new array with the contents.
Is there any reason why it is not coded that way?.
Most likely this is to allow you to reuse arrays, so you basically avoid (relatively costly) array allocation for some use cases. Another much smaller benefit is that caller can instantiate array slightly more efficiently, since toArray() must use 'java.lang.reflect.Array.newInstance' method.
As mentioned by others, there are a couple different reasons:
My guess is that if you already know the concrete type of
T
at the point you're callingtoArray(T[])
, it's more performant to just declare an array of whatever it is than make theList
implementation callArrays.newInstance()
for you -- plus in many cases you can re-use the array.But if it annoys you, it's easy enough to write a utility method:
(Note that there's no way to write
<E> E[] ToArray(Collection<E> c)
, because there's no way to create an array ofE
at runtime without aClass
object, and no way to get aClass
object forE
at runtime, because the generics have been erased.)This method is a holdover from pre-1.5 Java. Here is the link to javadoc
Back then it was the only way to convert a list to a reifiable array.
It is an obscure fact, but although you can store anything in the Object[] array, you cannot cast this array to more specific type, e.g.
Seemingly more efficient
List.toArray()
does just that, it creates a genericObject
array.Before Java generics, the only way to do a type-safe transfer was to have this cludge:
Thankfully generics made these kind of machinations obsolete. This method was left there to provide backward compatibility with pre 1.5 code.
Maybe so it has a runtime type?
From wiki: