Cannot create a generic array of <type>

W

Warren Tang

Hi,everybody

The following code:

ArrayList<Integer>[] indexedValues = new ArrayList<Integer>[5];

generates an error:

Cannot create a generic array of ArrayList<Integer>

Could someone explain this to me?

Regards,
Warren Tang
 
L

Lew

Warren said:
The following code:

ArrayList<Integer>[] indexedValues = new ArrayList<Integer>[5];

generates an error:

Cannot create a generic array of ArrayList<Integer>

Could someone explain this to me?

Sure. The short answer is that generics and arrays do not mix. Slightly longer, the Java Language Specification explicitly forbids arrays of non-reifiable types:

"An array creation expression specifies the element type, the number of levels of nested arrays, and the length of the array for at least one of the levels of nesting. ... It is a compile-time error if the element type is nota reifiable type".
<http://java.sun.com/docs/books/jls/third_edition/html/arrays.html#10.3>

Generic types like 'ArrayList<Integer>' are not reifiable, that is, you cannot actually create such a type at runtime due to type erasure.

The longer answer is that arrays are reifiable, therefore their element types must also be reifiable. Unlike generics, arrays carry their base type with them at run time - they "know" their type. Generic types do not. (Youcan get around this with a run-time type token, or RTTT, but that's a topic for another discussion.) So when you try to make an array of a generic type you deprive the array of information it needs. This the compiler won'tallow.

Back to the short answer: don't mix arrays and generics. There are a few conversion classes in the Collections framework that let you convert betweenthem, but use them sparingly and usually to go from array-land to collections-land to stay.

Arrays.asList
static <T> List<T> asList(T... a)
<http://download.oracle.com/javase/7/docs/api/java/util/Arrays.html#asList(T...)>
 
W

Warren Tang

Thanks for the info. If I use the reified version of the generic - i.e.
the erased version of the generic - ArrayList instead of
ArrayList<Integer>, the compile error goes away and there is no run-time
error either.

ArrayList<Integer>[] indexedValues = new ArrayList[5];

Although there is still a type safety warning.
 
M

markspace

Thanks for the info. If I use the reified version of the generic - i.e.
the erased version of the generic - ArrayList instead of
ArrayList<Integer>, the compile error goes away and there is no run-time
error either.

ArrayList<Integer>[] indexedValues = new ArrayList[5];

Although there is still a type safety warning.


How about :


ArrayList<ArrayList<Integer>> indexedValues =
new ArrayList<ArrayList<Integer>>();
 
W

Warren Tang

Thanks for the info. If I use the reified version of the generic - i.e.
the erased version of the generic - ArrayList instead of
ArrayList<Integer>, the compile error goes away and there is no run-time
error either.

ArrayList<Integer>[] indexedValues = new ArrayList[5];

Although there is still a type safety warning.


How about :


ArrayList<ArrayList<Integer>> indexedValues =
new ArrayList<ArrayList<Integer>>();

Sure. I just wanted to know why.
 
L

Lew

Warren said:
Thanks for the info. If I use the reified version of the generic - i.e.
the erased version of the generic - ArrayList instead of
ArrayList<Integer>, the compile error goes away and there is no run-time
error either.

ArrayList<Integer>[] indexedValues = new ArrayList[5];

Although there is still a type safety warning.

DO NOT USE RAW TYPES!!!

You get a warning because your code is not type safe. BAD!

DO NOT MIX ARRAYS AND GENERICS!!!

DO NOT USE RAW TYPES!!!
 
M

markspace

Thanks for the info. If I use the reified version of the generic - i.e.
the erased version of the generic - ArrayList instead of
ArrayList<Integer>, the compile error goes away and there is no run-time
error either.

ArrayList<Integer>[] indexedValues = new ArrayList[5];

Although there is still a type safety warning.


Because what you did is not type safe. It's also a terrible idea and
poor practice. Bosses and co-workers will not like this sort of thing.

Sure. I just wanted to know why.


What you have there is not the reified version of a generic. It's a raw
type. It has no parameter type. It's a really bad idea to use raw
types or to mix raw types and generics unless you must (there are a few
specific instances where you can't avoid it). Here, you can almost
certainly avoid raw types so do so.
 
W

Warren Tang

On 10/19/2011 3:11 AM, Warren Tang wrote:
Thanks for the info. If I use the reified version of the generic - i.e.
the erased version of the generic - ArrayList instead of
ArrayList<Integer>, the compile error goes away and there is no
run-time
error either.

ArrayList<Integer>[] indexedValues = new ArrayList[5];

Although there is still a type safety warning.


Because what you did is not type safe. It's also a terrible idea and
poor practice. Bosses and co-workers will not like this sort of thing.

Sure. I just wanted to know why.


What you have there is not the reified version of a generic. It's a raw
type. It has no parameter type. It's a really bad idea to use raw types
or to mix raw types and generics unless you must (there are a few
specific instances where you can't avoid it). Here, you can almost
certainly avoid raw types so do so.

Thanks for the suggestion. Though it's a local variable with controlled
usage, I'd better follow the best practice and use ArrayList instead of
arrays.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top