0

Good day everyone. My problem has been discussed many times on SO, but i cant find answer anyway. So, I need to store array of generics in my generic class instance:

public class GenericArrayStorage<Item> implements Iterable<Item> {

    private Item[] storage;
    ....
}

Obviously, I cant work with storage like with array of concrete objects (my IDE shows error Generic array creation on new Item[]). After some research i wrote this code:

@SuppressWarnings("unchecked")
public GenericArrayStorage() {
    ParameterizedType genericSuperclass = 
       (ParameterizedType) getClass().getGenericSuperclass(); //error
    Class clazz = (Class) genericSuperclass.getActualTypeArguments()[0];
    storage = (Item[]) Array.newInstance(clazz, 10);
}

But this leads to following error: java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType

I said OK and wrote this:

@SuppressWarnings("unchecked")
public GenericArrayStorage() {
    ParameterizedType pt = 
       (ParameterizedType) getClass().getGenericInterfaces()[0]; 
    Class clazz = (Class) pt.getActualTypeArguments()[0]; //error
    storage = (Item[]) Array.newInstance(clazz, 10);
}

This one causes another exception: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class. Sad but true.

Then I added .getClass() to pt.getActualTypeArguments()[0] and my constructor now don't throw any errors. However, when i try to work with this array after new GenericArrayStorage<Integer>(), it throws following: java.lang.ArrayStoreException: java.lang.Integer. This line causes exception: storage[0] = new Integer(1);

So, how could i work with generic array?

Everv0id
  • 1,634
  • 3
  • 22
  • 43
  • In your first attempt, you get a `java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType` because your class implements an interface. The superclass would be `java.lang.Object` and that is not a `ParametrizedType`. – Tunaki Feb 27 '15 at 21:21
  • @Tunaki It's clear now why i got those exceptions. But this doesn't answer the question: how could one implement a generic array storage without strange reflection issues? – Everv0id Feb 27 '15 at 21:24
  • See [this answer](http://stackoverflow.com/a/14659922/1743880). – Tunaki Feb 27 '15 at 21:27
  • 1
    What's the problem with this answer: http://stackoverflow.com/questions/529085/how-to-create-a-generic-array-in-java – m0skit0 Feb 27 '15 at 21:45
  • Side note: you won't have this problem if you use a `List` instead, code is much cleaner and understandable (`storage = new ArrayList<>()`) – m0skit0 Feb 27 '15 at 21:48

1 Answers1

0

The only way this works is if the value of Item is captured in a type definition. Ex:

StringStorage extends GenericArrayStorage<String> {
}

Then your getClass().getGenericSuperclass() should work as expected, returning String in this case.

Jonathan
  • 5,298
  • 33
  • 46