You can only declare array variables whose component type is a type parameter, but you cannot create the corresponding array objects. The type of E
is unknown at runtime, due to type erasure. The compiler does not know how to create an array of an unknown component type.
Similarly, you cannot create an array of concrete parameterized type.
A workaround is to use Array.newInstance
method:
Class<E> clazz;
E[] array = (E[])Array.newInstance(clazz, length) ;
However, this will give you an Unchecked Cast warning, because Array.newInstance
returns an Object
, and you are casting it to E[]
. You can suppress the warning using @SuppressWarnings
annotation. But, you need to pass the clazz
argument in that method, which should be the class type of E
type parameter.
There is a major difference between an array and generic types - i.e, arrays are reified (As already stated by @Marko in his answer). I would add a paragraph, from the book Effective Java - Item 29 on this topic:
This means that arrays know and enforce their element types at
runtime. As noted above, if you try to store a String into an array of Long, you’ll
get an ArrayStoreException. Generics, by contrast, are implemented by erasure
[JLS, 4.6]. This means that they enforce their type constraints only at compile
time and discard (or erase) their element type information at runtime. Erasure is
what allows generic types to interoperate freely with legacy code that does not use
generics (Item 23).
Because of these fundamental differences, arrays and generics do not mix
well. For example, it is illegal to create an array of a generic type, a parameterized
type, or a type parameter. None of these array creation expressions are legal: new
List<E>[]
, new List<String>[]
, new E[]
. All will result in generic array creation
errors at compile time.