Odd generics behaviour of List.toArray(T[])

arrays, java, list

Solution

you forgot to specify the type parameter for your List:

List<String> l = Arrays.asList("a", "b", "c");

in this case you can write safety:

String[] a = l.toArray(new String[0]);

without any cast.

Problem

I came across something very basic but extremely bewildering today. I needed to convert a list to an array. The list contained `String` instances. Perfect example of using `List.toArray(T[])`, since I wanted a `String[]` instance. It would not work, however, without explicitly casting the result to `String[]`. As a test scenario, I used the following code: ``` import java.util.Arrays; import java.util.List; public class MainClass { public static void main(String args[]) { List l = Arrays.asList("a", "b", "c"); String stuff[] = l.toArray(new String[0]); System.err.println(Arrays.asList(stuff)); } } ``` which does not compile. It's nearly an exact copy of the example in the javadoc, yet the compiler says the following: ``` MainClass.java:7: incompatible types found : java.lang.Object[] required: java.lang.String[] String stuff[] = l.toArray(new String[0]); ^ ``` If I add a cast to `String[]` it will compile AND run perfectly. But that is not what I expect when I looked at the signature of the toArray method: ``` <T> T[] toArray(T[] a) ``` This tells me that I shouldn't have to cast. What is going on? Edit: Curiously, if I change the list declaration to: ``` List<?> l = Arrays.asList("a", "b", "c"); ``` it also works. Or `List<Object>`. So it doesn't have to be a `List<String>` as was suggested. I am beginning to think that using the raw `List` type also changes how generic methods inside that class work. Second edit: I think I get it now. What Tom Hawtin wrote in a comment below seems to be the best explanation. If you use a generic type in the raw way, all generics information from that instance will be erased by the compiler.

Original source