Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this generics array creation not working as expected?

Tags:

java

generics

I have the following code where I'm creating an array and trying to store objects in it. At run time, I get an ArrayStoreException.

import java.lang.reflect.Array;

public class GenericsArrayCreation<T> {

    public static <T> void Test(T[] A){
        @SuppressWarnings("unchecked")
        T[] temp = (T[]) Array.newInstance(A.getClass(), A.length);
        for(int i = 0;i<temp.length;i++){
            temp[i] = A[i];
            System.out.println(temp[i].toString());
        }
    }

    public static void main(String[] args){
        String[] strs = {"a", "b", "c"};
        GenericsArrayCreation.Test(strs);
    }
}

I somehow understand that this is because of the statement

T[] temp = (T[]) Array.newInstance(A.getClass(), A.length);

Why is this wrong? A.getClass() at runtime returns a String, so temp should be an array of strings. In that case, why is the assignment temp[i] = A[i] not working?

like image 800
Poornima Prakash Avatar asked Aug 15 '13 09:08

Poornima Prakash


People also ask

Why Java does not allow generic array creation?

If generic array creation were legal, then compiler generated casts would correct the program at compile time but it can fail at runtime, which violates the core fundamental system of generic types.

Can you create an array of generic type?

No, we cannot create an array of generic type objects if you try to do so, a compile time error is generated.

How do you initialize a generic array in Java?

reflect. Array#newInstance to initialize our generic array, which requires two parameters. The first parameter specifies the type of object inside the new array. The second parameter specifies how much space to create for the array.

What are not allowed for generics?

Cannot Declare Static Fields Whose Types are Type Parameters. Cannot Use Casts or instanceof With Parameterized Types. Cannot Create Arrays of Parameterized Types. Cannot Create, Catch, or Throw Objects of Parameterized Types.


1 Answers

The type of A is java.lang.String[], rather than java.lang.String.

You want the component type of the array, rather than the array type itself.

Use this line instead:

T[] temp = (T[]) Array.newInstance(A.getClass().getComponentType(), A.length);

and the code runs fine.

like image 89
Vincent van der Weele Avatar answered Nov 15 '22 00:11

Vincent van der Weele