Creating Generic Array In Java

May 27, 2022
Creating Generic Array In Java



Overview

An array can be simply defined as a collection of items stored in contiguous memory locations. It is one such concept that every programmer, novice or expert is quite aware of but the Generic Array in Java is something that might be a new concept for you if you are new to Java programming. This article is about how to make a generic array in Java. We will look into arrays and Java Generics and will extensively discuss the java generic array creation process and why would we need it.

new java job roles

The Java Generics

Java Generics were introduced in JDK 5.0 primarily aiming to reduce errors in Java and to add an extra layer of abstraction over data types. This feature was indeed very helpful for developers as it removes repetitive casting in the code.

 

See this simple piece of code used to create a simple list in Java to store Integer type values:

List list = new LinkedList();
list.add(new Integer(0));
Integer index = list.iterator().next();

The compiler will result in an error in the last line as it would be unaware of what data type is to be returned. No line in this code guarantee that the return type of this list is Integer. The defined list could be holding any type of object that is why an explicit cast is required to ensure the data type.

 

To resolve the error, it requires a line of code with explicit casting like this:

Integer index = (Integer) list.iterator.next();

Such explicit casting statements often clutter your code and can also cause type-related runtime errors due to any unintentional mistakes. It would be much more convenient if the intention to use a specific data type could be mentioned so the compiler can directly ensure the correctness of such types. Java generics are used to cater to this issue.

 

See this code below, implementing the generics by changing the first line of the previous code snippet:

List<Integer> list = new LinkedList<>();

The addition of the diamond operator <> containing the required data type narrows down the specialization of this list to only Integer type. In other words, it specifies the type of data held inside the list and now the compiler can enforce this data type at compile time. This can make your significantly easier to read and manage.

Generic Array in Java

A generic array is different from a normal array in Java as it is initially made independent of any data type and the data type is eventually evaluated by the compiler at runtime.

The biggest difference between arrays and a generic array is of enforcing the type checking. Arrays usually store and check data type information at runtime whereas a Generic would check for data type at compile time and  the data type information would not even be available at runtime. Using the Java generic syntax mentioned before, we might be able to create a new generic array like this.

T[] elements = new T[size];

However, if we attempt this for a Java generic array creation, it will result in a compile time error because the information needed at the runtime for memory allocation will not be available.

Now, Consider the following complete code demonstration for a Java generic array creation

public <T> T[] myArr (int n)
{
    T[] genericsArray = new T[n];
    return genericsArray;
}

And the following method will be used at runtime:

public Object[] myArr(int n)

{
    Object[] genericsArray = new Object[n];
    return genericsArray;
}

Now,  if we call this method and try to store the result in an array of integer data type like this,

Integer[] myArr01 = myArr (5);

It will compile just fine but will result in a runtime error with a ClassCastException. It is because of assigning an Object[] to an Integer[] reference. The implicit casting done by the compiler would fail in converting an Object[] to our required type Integer[].

Creating a Generic array in Java

Considering all these previous points, it is quite evident that there is no straightforward method for Java generic arrays creation, but it is still possible to achieve this by some indirect methods.

The following two array-like structures can be used instead to simulate a Java generic Array.

– Using Object Array

This approach includes the use of an array of Objects type as a member of the main array class. We instantiate the main array class that can provide the data type as required along with that, getter and setter methods can be used to read or set the elements in the array. This can simulate the working of a Java generic array.

 

See this code demonstration below:

import java.util.Arrays;
class Array<T> {
    private final Object[] object_array;   //object array
    public final int len;
    // class constructor
    public Array(int len)

{
        // instantiate a new Object array of specified length
        object_array = new Object [len];
        this.len = len;
    }
    // getter method
    T getArr(int i)
    {
        @SuppressWarnings("unchecked")
        final T t = (T)object_array[i];
        return t;
    }

    // setter method

    void setArr(int i, T t)
    {
        object_array[i] = t;
    }
    @Override
    public String toString() {
        return Arrays.toString(object_array);
    }
}
class Main {
    public static void main(String[] args){
        final int length = 10;
        // creating an integer array
        Array<Integer>int_Arr = new Array(length);
        System.out.print("Integer generic array:" + " ");
        for (int i = 0; i < length; i++)
            int_Arr.set(i, i + 1);
        System.out.println(int_Arr);
        // creating a string array
        Array<String>str_Arr = new Array(length);
        System.out.print("String Generic Array:" + " ");
        for (int i = 0; i < length; i++)
            str_Arr.set(i, String.valueOf((char)(i + 65)));
        System.out.println(str_Arr);
    }
}
Output:
Integer Generic Array: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
String Generic Array: [A, B, C, D, E, F, G, H, I, J]

In the above code demonstration, A generic class array is defined. The object array is a member of the class, instantiated with a constructor and a length variable. The generic getter and setter methods are used to read and set an array element of a particular type.

While creating instances, we can specify the desired type. The two arrays of type Integer and String are then created and populated and at last, the contents of each of these instances are displayed using the overridden ‘toString’ method.

– Using Reflection class

Another method is to use a reflection class to get the working of a Java generic array whose type will only be known at the runtime. It is quite a similar approach to the previous one but with just one difference, here, the reflection class is used in the constructor itself to instantiate an object array by explicitly passing the data type information to the class constructor. It is passed to the Array.newInstance method of reflection.

 

The following code demonstrates the usage of reflection to create a Java generic array:

Import java.util.Arrays; 
class Array<T>
{
    private final T[] object_Arr;
    public final int length;
    // class constructor
    public Array(Class<T>dataType, int length)
    // creating a new array with the specified data type and length at runtime using reflection
    this.object_Arr = (T[]) java.lang.reflect.Array.newInstance(dataType, length);
        this.length = length;
    }
    // getter method
    Tget(int i) {
        Return object_Arr [i];
    }
    // assigning t to object_Arr [i]
    void setter(int i, T t) {
        object_Arr[i] = t;
    }
    @Override
    public String toString() {
        return Arrays.toString(object_Arr);
   }
}
class Main
  {
     public static void main(String[] args)
    {
        final int length = 6;
        // creating an array with Integer as data type
        Array<Integer>int_Arr = new Array(Integer.class, length);
        System.out.print("Integer Generic Array:" + " ");
        for (int i = 0; i < length; i++)
            int_Array.set(i, i + 5);
        System.out.println(int_Arr);
        // creating an array with String as data type
        Array<String>str_Arr = new Array(String.class, length);
        System.out.print("String Generic Array:" + " ");
       
        for (int i = 0; i < length; i++)
            str_Array.set(i, String.valueOf((char)(i + 97)));
        System.out.println(str_Arr);
    }
  }
Output:

Integer Generic Array: [5, 10, 15, 20, 25, 30]

String Generic Array: [a, b, c, d, e, f]

Conclusion

The Java Generic array cannot be directly created as we cannot have a parameterized type assigned to an array reference. We looked into the reasons behind why it cannot be done However, there are some indirect ways to utilize the functionality of genetics with Arrays using object arrays and reflection features.

Wrapping it up, we can say that arrays and generics do not go hand in hand in Java as arrays are covariant while generics are invariant but Java, being such a dynamic language, it also offers some great alternatives to get the task done.

Also Read: Java Expressions with Examples

new Java jobs



author

shaharyar-lalani

Shaharyar Lalani is a developer with a strong interest in business analysis, project management, and UX design. He writes and teaches extensively on themes current in the world of web and app development, especially in Java technology.


Candidate signup

Create a free profile and find your next great opportunity.

JOIN NOW

Employer signup

Sign up and find a perfect match for your team.

HIRE NOW

How it works

Xperti vets skilled professionals with its unique talent-matching process.

LET’S EXPLORE

Join our community

Connect and engage with technology enthusiasts.

CONNECT WITH US