1

This is not a question how to do things. It is a question of why is it the way it is.

Arrays in Java know their component type at run time, and because of type erasure we cannot have array objects of generic type variables. Array types involving generics are allowed and checked for sound read/write, the only issue seem to be the allocator expressions.

Notice that the Java compiler also disallows the following:

Pong<Integer> lotsofpong [] = new Pong<Integer>[100];

...where Pong is just any old parametric class. There is nothing unknown here. Yes, at run-time, lotsofpong would just be an array of Pong, but I cannot see a reason why the compiler cannot remember the type parameter for compile-time purposes. Well, it actually does remember it, because those types exist at compile time, so the only problem seems to be the refusal to give the allocator at compile-time a particular generic-parameter-involving component type.

Even if the parameter of Pong was a generic type variable that should not make a difference either. The dynamic array would still be an array of Pong, requiring per element the size of a Pong, which does not depend on its type parameter.

Yes, I know there are ways around it - either use casts (perhaps with SuppressWarning) from the non-parametric type, or subclass Pong<Integer> with a non-parametric class and use that type instead. But is there a reason why this kind of allocator is not allowed?

fledermaus
  • 33
  • 3
  • http://stackoverflow.com/questions/9542076/array-of-parameterized-types, http://stackoverflow.com/questions/529085/java-how-to-generic-array-creation, and http://www.ibm.com/developerworks/java/library/j-jtp01255/index.html might be of interest. – jedwards May 27 '13 at 07:42
  • 1
    Effective java item 25. I don't really remember it, but you could try this [google books link](http://books.google.com/books?id=ka2VUBqHiWkC&pg=PA119&lpg=PA119&dq=effective+java+generic+array&source=bl&ots=yYIoOin1VY&sig=OLgj07rc_1YGLtguS2E1slt2iDc&hl=en&sa=X&ei=Kw6jUZDUCbTV4ASajIGIAw&ved=0CC4Q6AEwAA#v=onepage&q=effective%20java%20generic%20array&f=false) – zeller May 27 '13 at 07:43

1 Answers1

1

Based on the link that was provided by Zeller (based on Josh Bloch - 'Effective Java Book').

Arrays are not safe because the following code will compile:

String strings [] = {"Foo"};
Object objects [] = strings;
objects[0] = 1;

You will get a special exception at run-time: java.lang.ArrayStoreException. Java run-time cheks at run-time that you put an appropriate type into the array.

Assigning an array to an array of its super type is called 'Covariance'.

Generics are guaranteed to be safe at compile-time.

If the code snippet that you mentioned in the question was able to be compiled, the following code would also compiles:

Pong<Integer> integerPongs [] = new Pong<Integer>[100];
Object objectPongs [] = integerPongs;
objectPongs[0] = new Pong<String>();
Pong<Integer> stringPong = integerPongs[0]; // ClassCastException

Our code becomes not safe therefore it was forbidden by the specification.

The reason that :

objectPongs[0] = new Pong<String>();

does not throw java.lang.ArrayStoreException is because the run-time type of each instance of Pong is always Pong since Generics is a compile-time mechanism.

Oz Molaim
  • 2,016
  • 4
  • 20
  • 29