3

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!

4
  • 1
    After erasure, the getStringArr should return Object[] -> no it doesn't, because it does not create a generic array. You're the one passing in a String[] so the getStrArr doesn't have to do any array creation at all Commented Sep 25, 2021 at 10:51
  • @Lino, thanks for the reply. the return type of getStringArr is T[], according to erasure => Replace all type parameters in generic types with their bounds or Object if the type parameters are unbounded. so the return type should becomes Object[]. I am referencing docs.oracle.com/javase/tutorial/java/generics/erasure.html Commented Sep 25, 2021 at 10:54
  • When using generics the compiler "cheats" by adding implicit casting. Because you pass a String[] into the method, and then return it directly, the final cast (to String[]) when assigning the return value of getStrArr() to strArr will work, because the returned value is a String[] Commented Sep 25, 2021 at 12:00
  • @Lino, you are right, I missed the very basic thing. Thanks Commented Sep 25, 2021 at 12:47

1 Answer 1

1

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[].

Sign up to request clarification or add additional context in comments.

2 Comments

thanks a lot for the response. Clear explanation on the first part, understood now, thanks a lot. For the second part, I know it is a problem to create array with generic class, just as you explained. But it is not quite related to using generic parameter to create array, which is new T[]. So after your explanation, my understanding is we cannot use new T[] because it is not possible to do the casting. Hope I got it right.
I have removed the second part related to parameterized arrays. Generic arrays cause problems related to casting and that is why they are not allowed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.