Why can't I create an array of a generic type?

The bottom line is that the class that represents the array has to know the component type. Hence the method on the Class object:

public Class<?> getComponentType()
Returns the Class representing the component type of an array. If this class does not represent an array class this method returns null.

So when you would try:

 A[] a = new A[0];

At compile time, it's obvious that we don't know the type, as it's a generic parameter. At runtime, we don't know the type due to type erasure. So instantiating the array is impossible.

Think of the above statement as equivalent to:

 A[] a = (A[])Array.newInstance(???, 0);

And due to type erasure, we can't get the class of A at runtime.

It was asked why not have the compiler reduce to Object[] or Number[] or something like that?

It's because a different Class will be returned depending on the component type. So:

 new Object[0].getClass() 
 new Integer[0].getClass()

are not the same class. In particular the "getComponentType()" method on the class would return different values.

So if you reduce it to Object[] instead of A[], you're not actually getting back something of type A[], you're getting back Object[]. Object[] cannot be cased to Integer[] and will yield a ClassCastException.


Type erasure is the word you are looking for. It basically means that the generic information is erased at compile time. The main reason for this is backward compatibility. Older programs should still run on the new java virtual machine.


In Java, the type system for arrays and generics is incompatible. There are two main areas of discrepancy: dynamic vs static type check and covariance.

Generics are statically checked: that is, the compiler makes sure that the type definitions are coherent. "Type erasure" was a compromise to ensure backwards-compatibility in the JVM. After compilation, generic type definition is no longer available. E.g. List<T> becomes List.

In contrast, arrays are dynamically type-checked. Consider the following example:

String strings[] = {"a","b","c"};
Object simple[] = strings;
simple[0] = new Object(); // Runtime error -> java.lang.ArrayStoreException 

Covariance is the inheritance relationship of a container based on the content. Given types A,B and a container C, if B isAssignableFrom(A) => C isAssignable C.

Arrays in Java are covariant, in the previous example, Given that Class<Object>.isAssignableFrom(Class<String>) => Object[] is assignable from String[]

In contrast, generic types are not covariant in Java. Using the same example:

List<String> stringList = new ArrayList<String>();
List<Object> objectList = stringList; // compiler error - this is not allowed.

Given the type erasure of the generics implementation, type information is lost in translation and therefore the dynamic type check would be compromised if you could create an array of a generic type.

Further read on the complications and implications of these issues: Arrays in Java Generics