javaarraysgenericserasure

Generic Array initialisation


I have read through different articles which talks about why we cannot create generic array in java, but still I don't quite understand why.

For example, it this post, it assumed if generic array initialisation is possible, there will be casting issue after erasure. You can find the details in section 2. Considerations When Using Generic Arrays. In simplest term, the generic array becomes an Object Array after erasure, and if the generic type is String, java will fail to cast Object[] to String[].

However, I created a generic class with a simple function,

// Test.java
public class Test<T> {
    public T[] getStrArr(T[] arr) {
        return arr;
    }
}

//Main.java
public static void main(String[] args) {
       Test<String> test = new Test<>();
        String[] strArr = test.getStrArr(new String[]{"A", "B", "C"});
}

After erasure, the getStringArr should return Object[], and it is able to cast to String[] without any problem.

Another stackoverflow post stated that:

arrays (unlike generics) contain, at runtime, information about its component type. So you must know the component type when you create the array. Since you don't know what T is at runtime, you can't create the array.

but erasure will change T into Object type, so compiler can create array with Object type.

There are other posts with similar explanation but cannot really resolve my doubt.

Please help!


Solution

  • After erasure, the getStringArr should return Object[], and it is able to cast to String[] without any problem.

    Return type of the getStrArr, after type erasure, would be Object[] but, in your code, it is returning arr which is of type String[]. That is why there is not ClassCastException in your code.

    Consider the following method (suppose generic arrays were allowed):

    public T[] foo() {
        return new T[5];                  
    } 
    

    After type erasure, new T[5] will be replaced by new Object[5]. Now if the calling code calls this method as:

    String[] strArr = obj.foo();
    

    It will lead to ClassCastException because Object[] cannot be casted to String[].