Here's a question, this first code listing compiles just fine (JDK 1.6 | JDK 1.7):
ArrayList<String> a = new ArrayList<String>();
String[] s = a.toArray(new String[0]);
However, if I declare the List
reference as a raw type:
ArrayList a = new ArrayList();
String[] s = a.toArray(new String[0]);
I get a compiler error saying the String[]
is required but Object[]
was found.
This means my compiler is interpreting the generic method as returning Object[]
despite of receiving a String[]
as its argument.
I doubled-checked the toArray(myArray)
method signature:
<T> T[] toArray(T[] a);
Therefore it is a parameterized method whose type parameter <T>
has no relation whatsoever with that of the List (i.e. <E>
).
I have no idea how using a raw type here affects the evaluation of parameterized methods using independent type parameters.
It's not exactly what you'd expect, but if you refer to a generic class in raw form, you lose the ability to use generics in any way for instance members. It's not restricted to generic methods either, check out this:
public class MyContainer<T> {
public List<String> strings() {
return Arrays.asList("a", "b");
}
}
MyContainer container = new MyContainer<Integer>();
List<String> strings = container.strings(); //gives unchecked warning!
This is the relevant part of the JLS (4.8):
The type of a constructor (§8.8), instance method (§8.4, §9.4), or non-static field (§8.3) M of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C.