1

I need to create an array of generics at runtime and, because of java type erasure, I am using super type tokens to achieve that. I created the following abstract class:

public abstract class TypeReference<T> {

    private final Type type;

    public TypeReference() {
        Type superclass = getClass().getGenericSuperclass();
        type = ((ParameterizedType) superclass).getActualTypeArguments()[0];
    }

    public Type getType() {
        return type;
    }
}

and I'm trying to generate my array with the following code:

public static void main(String[] args) {
    TypeReference<LinkedListNode<Integer>> token = new TypeReference<>() {};
    LinkedListNode<Integer>[] array = generateRandomArray(10, token);
}

public static <T> T[] generateRandomArray(int size, TypeReference<T> c) {
    return (T[]) Array.newInstance(c.getType().getClass(), size);
}

This solution doesn't work because c.getType().getClass() is returning ParameterizedType. I should pass c.getType() (which is LinkedListNode<Integer>), but this last solution doesn't compile since Type cannot be cast to Class<?>.

Do you know how can I leverage the Super Type Token to generate the array?

Thank you.

Pasquale
  • 389
  • 3
  • 11
  • "I need to create an array of generics" can you explain why? This feels like an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). – Andy Turner Nov 24 '21 at 08:50
  • I have different parameterized classes in my code and I need to create different arrays of all these classes. Thus, I want to centralize the creation of my arrays inside a single method, which will get in input the array size and the class type. – Pasquale Nov 24 '21 at 08:53
  • 1
    All you've done there is to restate that you want to create arrays of generic element type. Since you can't actually do that in Java (because of type erasure), I'm asking why you need to, as opposed to, for example, using Lists. – Andy Turner Nov 24 '21 at 08:56
  • Since your type reference's type parameter could be a parameterized type as well you might have to do some type checks to get the raw type/class. Due to type erasure, at runtime you'd only get a `LinkedListNode[]` anyway. But as Andy said you seem to try to use this to solve another problem, so if you'd tell us what exactly you're trying to solve there might be an easier and more robust solution. – Thomas Nov 24 '21 at 08:56
  • @AndyTurner it's an assignment request – Pasquale Nov 24 '21 at 08:58
  • 1
    You need to get the `Class` object of the raw type of the type you want (i.e. in this case, `LinkedList.class`). You would have to check whether your `c.getType()` is a `ParameterizedType`, and if it is, call `.getRawType()` on it. If `c.getType()` is a `TypeVariable` or `WildcardType` you can't do anything with it. But the whole thing with using `TypeReference` seems unnecessarily complicated since all you need is the raw type. – newacct Nov 26 '21 at 16:09
  • Yes, I found it as final solution. The only minor drawback is that in this way I get the casting warning... – Pasquale Nov 26 '21 at 16:26

0 Answers0