views:

178

answers:

5

There are plenty of questions on stackoverflow from people who have attempted to create an array of generics like so:

ArrayList<Foo>[] poo = new ArrayList<Foo>[5];

And the answer of course is that the Java specification doesn't allow you to declare an array of generics.

My question however is why ? What is the technical reason underlying this restriction in the java language or java vm? It's a technical curiosity I've always wondered about.

+9  A: 

Arrays are reified - they retain type information at runtime.

Generics are a compile-time construct - the type information is lost at runtime. This was a deliberate decision to allow backward compatibility with pre-generics Java bytecode. The consequence is that you cannot create an array of generic type, because by the time the VM wants to create the array, it won't know what type to use.

danben
+5  A: 

See Effective Java, Item 25.

JRL
Effective Java is really a great book. I saw many questions I got during interviews on this book.
zihaoyu
+2  A: 

Here is an old blog post I wrote where I explain the problem: Java generics quirks

See How do I generically create objects and arrays? from Angelika Langer's Java Generics FAQ for a workaround (you can do it using reflection). That FAQ contains everything you ever want to know about Java generics.

Jesper
A: 

There is little use in having a generic on an array. Before generics existed (prior to 1.5) an array explicitly on declaration expressed what type of element it was meant to store...

String[] array = new String[5];

Collections however did not have the same benefit. Generics where brought into the language to help with that (among other less used features). If you look at the equivalent list construct...

List<String> list = new ArrayList<String>(5);

You'll notice that the object type is List. The generic helps at compile time decide what kind of elements to insert at said list. Without it, there would be no compile time control as to the elements that could be put into the list.

Arrays never had that problem. At compile time they know exactly what type of elements they will hold, making generics unnecessary in their context.

Enmanuel Rivera
A: 

You are forced to use

ArrayList<Foo>[] poo = new ArrayList[5];

which will give you an unchecked warning. The reason is that there is a potential type safety issue with generics and the runtime type-checking behavior of Java arrays, and they want to make sure you are aware of this when you program. When you write new ArrayList[...], you are creating something which will check, at runtime, everything that gets put into it to make sure that it is an instance of ArrayList. Following this scheme, when you do new ArrayList<Foo>[...], then you expect to create something that checks at runtime everything that gets put into it to make sure it is an instance of ArrayList<Foo>. But this is impossible to do at runtime, because there is no generics info at runtime.

newacct