How to create a general array in Java?

Posted by TomatoLover on Thu, 12 Dec 2019 15:56:55 +0100

Due to the implementation of Java generics, you cannot have the following code:

public class GenSet<E> {
    private E a[];

    public GenSet() {
        a = new E[INITIAL_ARRAY_LENGTH]; // error: generic array creation
    }
}

How to achieve this while maintaining type safety?

I saw this solution on the Java Forum:

import java.lang.reflect.Array;

class Stack<T> {
    public Stack(Class<T> clazz, int capacity) {
        array = (T[])Array.newInstance(clazz, capacity);
    }

    private final T[] array;
}

But I really don't know what happened.

#1 building

A simple but messy solution is to nest the second "holder" class in the main class and use it to hold the data.

public class Whatever<Thing>{
    private class Holder<OtherThing>{
        OtherThing thing;
    }
    public Holder<Thing>[] arrayOfHolders = new Holder<Thing>[10]
}

#2 building

I wrote this code snippet to instantiate in a reflective way the class passed by a simple automated test utility.

Object attributeValue = null;
try {
    if(clazz.isArray()){
        Class<?> arrayType = clazz.getComponentType();
        attributeValue = Array.newInstance(arrayType, 0);
    }
    else if(!clazz.isInterface()){
        attributeValue = BeanUtils.instantiateClass(clazz);
    }
} catch (Exception e) {
    logger.debug("Cannot instanciate \"{}\"", new Object[]{clazz});
}

Please note the following:

    if(clazz.isArray()){
        Class<?> arrayType = clazz.getComponentType();
        attributeValue = Array.newInstance(arrayType, 0);
    }

Used for array initialization, where Array.newInstance (class of array, size of array). Classes can be primitive (int.class) and object (Integer.class).

Bean utils is part of Spring.

#3 building

Also look at this Code:

public static <T> T[] toArray(final List<T> obj) {
    if (obj == null || obj.isEmpty()) {
        return null;
    }
    final T t = obj.get(0);
    final T[] res = (T[]) Array.newInstance(t.getClass(), obj.size());
    for (int i = 0; i < obj.size(); i++) {
        res[i] = obj.get(i);
    }
    return res;
}

It converts a list of objects of any type to an array of the same type.

#4 building

To extend more dimensions, simply add [] and dimension parameters to newInstance() (t is the type parameter, cls is class < T >, d1 to d5 are integers):

T[] array = (T[])Array.newInstance(cls, d1);
T[][] array = (T[][])Array.newInstance(cls, d1, d2);
T[][][] array = (T[][][])Array.newInstance(cls, d1, d2, d3);
T[][][][] array = (T[][][][])Array.newInstance(cls, d1, d2, d3, d4);
T[][][][][] array = (T[][][][][])Array.newInstance(cls, d1, d2, d3, d4, d5);

For more information, see Array.newInstance() .

#5 building

It may not be related to this problem, but there is a "generic array creation" error when I use it

Tuple<Long,String>[] tupleArray = new Tuple<Long,String>[10];

I found the following works of @ SuppressWarnings({"unchecked"}) (and I worked for @ SuppressWarnings({"unchecked"}):

 Tuple<Long, String>[] tupleArray = new Tuple[10];

Topics: Java Spring