I can, and will use an iterator instead of making an array sometimes, but this just always seemed strange to me. Why does the get(x) method know what it is returning, but toArray() defaults to Objects? Its like half way into designing it they decided this wasn't needed here??
As the intention of the question seems to be not just about getting around using toArray()
with generics, rather also about understanding the design of the methods in the ArrayList
class, I would like to add:
ArrayList
is a generic class as it is declared like
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
which makes it possible to use Generic methods such as public E get(int index)
within the class.
But if a method such as toArray()
is not returning E
, rather E[]
then things start getting a bit tricky. It would not be possible to offer a signature such as public <E> E[] toArray()
because it is not possible to create generic arrays.
Creation of arrays happen at runtime and due to Type erasure, Java runtime has no specific information of the type represented by E
. The only workaround as of now is to pass the required type as a parameter to the method and hence the signature public <T> T[] toArray(T[] a)
where clients are forced to pass the required type.
But on the other hand, it works for public E get(int index)
because if you look at the implementation of the method, you would find that even though the method makes use of the same array of Object to return the element at the specified index, it is casted to E
E elementData(int index) {
return (E) elementData[index];
}
It is the Java compiler which at the compile time replaces E
with Object