Generic Downcasting vs Non-generic downcasting

Viewed 30

T is Integer on runtime then how downcasting is being allowed here which isnt allowed in a non-generic class

//Allowed here 

class Generic<T>{
        Generic() {
        T[] array = (T[])new Object[5];     
} 
}

//Not Allowed here

class NonGeneric{
NonGeneric() {
        Integer[] array = (Integer[])new Object[5];
}
1 Answers

Type erasure is a bit weird.

new Object[5] always creates a new Object[], never an Integer[]. If you cast an Object[] to an Integer[], you get a ClassCastException.

A generic of type T is converted to Object at runtime but when using it, the returned T values are converted to the actual types (e. g. Integer).

The generic type T[] is actually Object[] at runtime and it will throw an exception when casting to the actual type (e. g. if T is Integer, casting the T[] to Integer[] will fail. Even the following will fail:

<T> T[] test() {
    return (T[])new Object[5];
} 

//where using it
Integer[] arr = test();

As T[] is Object[] at runtime, (T[])new Object[5] will work. However, after it is returned, it (still Object[] is implicitly casted to Integer[] and that fails with a ClassCastException.

At runtime, the aforementioned code would look like this:

Object[] test() {
    return (Object[])new Object[5];
} 

//where using it
Integer[] arr = (Integer[]) test();
Related