title: Odd generics behaviour of List.toArray(T[])
body: <p>I came across something very basic but extremely bewildering today. I needed to convert a list to an array. The list contained <code>String</code> instances. Perfect example of using <code>List.toArray(T[])</code>, since I wanted a <code>String[]</code> instance. It would not work, however, without explicitly casting the result to <code>String[]</code>. </p>
  
  <p>As a test scenario, I used the following code:</p>
  
  <pre><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));
      }
  }
  </code></pre>
  
  <p>which does not compile. It's nearly an exact copy of the example in the <a href="http://java.sun.com/javase/6/docs/api/java/util/List.html#toArray(T[])" rel="noreferrer">javadoc</a>, yet the compiler says the following:</p>
  
  <pre><code>MainClass.java:7: incompatible types
  found   : java.lang.Object[]
  required: java.lang.String[]
      String stuff[] = l.toArray(new String[0]);
                            ^
  </code></pre>
  
  <p>If I add a cast to <code>String[]</code> it will compile AND run perfectly. But that is not what I expect when I looked at the signature of the toArray method:</p>
  
  <pre><code>&lt;T&gt; T[] toArray(T[] a)
  </code></pre>
  
  <p>This tells me that I shouldn't have to cast. What is going on?</p>
  
  <p>Edit:</p>
  
  <p>Curiously, if I change the list declaration to:</p>
  
  <pre><code>List&lt;?&gt; l = Arrays.asList("a", "b", "c");
  </code></pre>
  
  <p>it also works. Or <code>List&lt;Object&gt;</code>. So it doesn't have to be a <code>List&lt;String&gt;</code> as was suggested. I am beginning to think that using the raw <code>List</code> type also changes how generic methods inside that class work.</p>
  
  <p>Second edit:</p>
  
  <p>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.</p>