In short, this won't compile:
public <A> void test() {
A[] temp = new A[]{};
}
Is it because of problems with backward compatibility, or is it something fundamental in the language design that prevents it?
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.