Resolve Generic Array Creation Error in Java

Mehvish Ashiq Aug 09, 2022
  1. Demonstration of the generic array creation Error in Java
  2. Possible Causes for generic array creation Error in Java
  3. Possible Solutions to Eradicate generic array creation Error in Java
Resolve Generic Array Creation Error in Java

This tutorial illustrates the generic array creation error via code sample and highlights why we have this error while creating a generic array. This discussion will lead to the solution where we will learn how to create a generic array using the Object array and reflect feature.

Demonstration of the generic array creation Error in Java

Example Code (DemoGenArray.java Class):

import java.util.Arrays;

public class DemoGenArray<T> {

    private T[] genericArray;

    DemoGenArray(int size) {
        genericArray = new T[size];//<----This Line Has Generic Array Creation Error
    }

    public T get(int index) {
        return (T) genericArray[index];
    }

    public void set(int index, T item) {
        genericArray[index] = item;
    }

    @Override
    public String toString() {
        return Arrays.toString(genericArray);
    }
}

In this class, we try to create and initialize a generic array with the specified array size. Further, we add elements to the array and return the items individually from the given index.

The toString() returns the whole array at once.

The issue is that we have a generic array creation error at the line we are pointing out in the constructor. Let’s explore the possible causes for this error which will help us to move towards its solution.

Possible Causes for generic array creation Error in Java

We are trying to create a generic array in our code, which is impossible in Java. It is because Java consciously decides to explicitly stop these syntaxes from working.

Remember, arrays are covariant (we can assign sub-type to its super-type reference) in Java while generics are not.

private T[] genericArray;
genericArray = new T[size];

The above two lines of code are the same as given below. You can use any one of them.

private T[] genericArray = new T[size];

It happens due to the type-erasure that Java implements. It is a process carried out by the Java compiler.

It removes parameterized types in generics and maps them to raw types in the byte code.

Remember, the byte code doesn’t have any details on generics. Using the type T will be fine at compile-time but has no meaning at run-time.

In other ways, we can circumvent this restriction that are given below with code examples. Let’s learn each of them below.

Possible Solutions to Eradicate generic array creation Error in Java

As we already know, the compiler does not have any information regarding parameterized types at run-time. So, whenever we are required to use generics, it is good to prefer and use the list component of the Java Collections framework instead of using arrays.

However, we can still create array-like generic structures, but this solution depends on whether it is checked or unchecked. We use the Object array if it is unchecked.

In the case of checked, we can use Java’s reflect feature. Let’s see how each of them works.

Solution 1: Use Object Array

Example Code (DemoGenArray.java class):

import java.util.Arrays;

public class DemoGenArray<T> {

    private Object[] genericArray;

    DemoGenArray(int size) {
        genericArray = new Object[size];
    }


    public T get(int index) {
        return (T) genericArray[index];
    }

    public void set(int index, T item) {
        genericArray[index] = item;
    }

    @Override
    public String toString() {
        return Arrays.toString(genericArray);
    }
}

Example Code (GenArray.java class):

public class GenArray {
    public static void main(String[] args) {

        DemoGenArray<String> strArray = new DemoGenArray(3);
        strArray.set(0, "one");
        strArray.set(1, "two");
        strArray.set(2, "three");

        DemoGenArray<Integer> intArray = new DemoGenArray(3);
        intArray.set(0, 10);
        intArray.set(1, 20);
        intArray.set(2, 30);

        DemoGenArray<Double> doubleArray = new DemoGenArray(3);
        doubleArray.set(0, 15.0);
        doubleArray.set(1, 110.0);
        doubleArray.set(2, 10.0);

        System.out.println("Integer Array: " + intArray);
        System.out.println("String Array: " + strArray);
        System.out.println("Double Array: " + doubleArray);
    }
}

Output:

Integer Array: [10, 20, 30]
String Array: [one, two, three]
Double Array: [15.0, 110.0, 10.0]

Here, we use the Object array to simulate the generic array because the DemoGenArray class is unchecked (weak typing). We can use this approach if we know that no type checking would be performed on objects passed as the arguments.

Further, we use generic get() and set() methods to return value and set value respectively. The get() method uses an explicit cast to T where T acts like a placeholder for the generics and represents any value/element.

This works fine if we use set() and get() methods and do not let the user directly access the Object array. Coming to the GenArray class, which contains the main() method.

Here, we create the instance of the DemoGenArray class.

We pass the required type while instantiating the DemoGenArray class and populating them. After that, we use the toString() method to write the contents of all instances.

Solution 2: Use reflect Feature

Example Code (DemoGenArray.java class):

import java.lang.reflect.Array;
import java.util.Arrays;

public class DemoGenArray<T> {

    private T[] genericArray;

    DemoGenArray(Class<T> classType, int size) {
       genericArray = (T[]) Array.newInstance(classType, size);
    }


    public T get(int index) {
        return (T) genericArray[index];
    }

    public void set(int index, T item) {
        genericArray[index] = item;
    }

    @Override
    public String toString() {
        return Arrays.toString(genericArray);
    }
}

Example Code (GenArray.java class):

public class GenArray {

    public static void main(String[] args) {
        DemoGenArray<String> strArray = new DemoGenArray(String.class, 3);
        strArray.set(0, "one");
        strArray.set(1, "two");
        strArray.set(2, "three");

        DemoGenArray<Integer> intArray = new DemoGenArray(Integer.class, 3);
        intArray.set(0, 10);
        intArray.set(1, 20);
        intArray.set(2, 30);

        DemoGenArray<Double> doubleArray = new DemoGenArray(Double.class, 3);
        doubleArray.set(0, 15.0);
        doubleArray.set(1, 110.0);
        doubleArray.set(2, 10.0);

        System.out.println("Integer Array: " + intArray);
        System.out.println("String Array: " + strArray);
        System.out.println("Double Array: " + doubleArray);
    }
}

Output:

Integer Array: [10, 20, 30]
String Array: [one, two, three]
Double Array: [15.0, 110.0, 10.0]

Here, we are using the reflection class to create the generic array whose type will only be known at run-time. This solution is similar to Solution 1 except for two differences in the DemoGenArray class.

First, we have a constructor in the DemoGenArray class that accepts two arguments, type and size of the array. Second, we initialize the genericArray using Array.newInstance() method.

The Array.newInstance() method creates a new array using the given dimension (size of the array) and component type.

Mehvish Ashiq avatar Mehvish Ashiq avatar

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

LinkedIn GitHub Facebook

Related Article - Java Error