Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java generics in ArrayList.toArray()

Say you have an arraylist defined as follows:

ArrayList<String> someData = new ArrayList<>(); 

Later on in your code, because of generics you can say this:

String someLine = someData.get(0); 

And the compiler knows outright that it will be getting a string. Yay generics! However, this will fail:

String[] arrayOfData = someData.toArray(); 

toArray() will always return an array of Objects, not of the generic that was defined. Why does the get(x) method know what it is returning, but toArray() defaults to Objects?

like image 590
Rabbit Guy Avatar asked Apr 13 '16 12:04

Rabbit Guy


People also ask

What is toArray method?

The Java ArrayList toArray() method converts an arraylist into an array and returns it. The syntax of the toArray() method is: arraylist.toArray(T[] arr) Here, arraylist is an object of the ArrayList class.

Is it possible to have a generic ArrayList of Java arrays?

Notice that we can't use generics while creating the array because java doesn't support generic array. So if we try to use below code, it will produce compile time error as “Cannot create a generic array of List<String>”.

What is the use of toArray () in Java?

The toArray() method of ArrayList is used to return an array containing all the elements in ArrayList in the correct order.


1 Answers

If you look at the implementation of toArray(T[] a) of ArrayList<E> class, it is like:

public <T> T[] toArray(T[] a) {     if (a.length < size)         // Make a new array of a's runtime type, but my contents:         return (T[]) Arrays.copyOf(elementData, size, a.getClass());     System.arraycopy(elementData, 0, a, 0, size);     if (a.length > size)         a[size] = null;     return a; } 

Problem with this method is that you need to pass array of the same generic type. Now consider if this method do not take any argument then the implementation would be something similar to:

public <T> T[] toArray() {     T[] t = new T[size]; // compilation error     return Arrays.copyOf(elementData, size, t.getClass()); } 

But the problem here is that you can not create generic arrays in Java because compiler does not know exactly what T represents. In other words creation of array of a non-reifiable type (JLS §4.7) is not allowed in Java.

Another important quote from Array Store Exception (JLS §10.5):

If the component type of an array were not reifiable (§4.7), the Java Virtual Machine could not perform the store check described in the preceding paragraph. This is why an array creation expression with a non-reifiable element type is forbidden (§15.10.1).

That is why Java has provided overloaded version toArray(T[] a).

I will override the toArray() method to tell it that it will return an array of E.

So instead of overriding toArray(), you should use toArray(T[] a).

Cannot Create Instances of Type Parameters from Java Doc might also be interesting for you.

like image 95
justAbit Avatar answered Sep 22 '22 17:09

justAbit