Cannot create a generic array of <type>

Discussion in 'Java' started by Warren Tang, Oct 19, 2011.

  1. Warren Tang

    Warren Tang Guest

    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
     
    Warren Tang, Oct 19, 2011
    #1
    1. Advertising

  2. Warren Tang

    Warren Tang Guest

    On 10/19/2011 12:06 PM, Warren Tang wrote:
    > 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


    Finally found a good article explaining this. It's about Type Erasure:
    http://code.stephenmorley.org/articles/java-generics-type-erasure/
     
    Warren Tang, Oct 19, 2011
    #2
    1. Advertising

  3. Warren Tang

    Lew Guest

    Warren Tang wrote:
    > 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...)>

    --
    Lew
     
    Lew, Oct 19, 2011
    #3
  4. Warren Tang

    Warren Tang Guest

    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.
     
    Warren Tang, Oct 19, 2011
    #4
  5. Warren Tang

    markspace Guest

    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.



    How about :


    ArrayList<ArrayList<Integer>> indexedValues =
    new ArrayList<ArrayList<Integer>>();
     
    markspace, Oct 19, 2011
    #5
  6. Warren Tang

    Warren Tang Guest

    On 10/19/2011 7:50 PM, markspace wrote:
    > 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.

    >
    >
    > How about :
    >
    >
    > ArrayList<ArrayList<Integer>> indexedValues =
    > new ArrayList<ArrayList<Integer>>();
    >
    >


    Sure. I just wanted to know why.
     
    Warren Tang, Oct 19, 2011
    #6
  7. Warren Tang

    Lew Guest

    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.


    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!!!

    --
    Lew
     
    Lew, Oct 19, 2011
    #7
  8. Warren Tang

    markspace Guest

    On 10/19/2011 9:43 AM, Warren Tang wrote:
    > On 10/19/2011 7:50 PM, markspace wrote:
    >> 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.
     
    markspace, Oct 19, 2011
    #8
  9. Warren Tang

    Warren Tang Guest

    On 10/20/2011 3:21 AM, markspace wrote:
    > On 10/19/2011 9:43 AM, Warren Tang wrote:
    >> On 10/19/2011 7:50 PM, markspace wrote:
    >>> 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.
     
    Warren Tang, Oct 21, 2011
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Hessam
    Replies:
    0
    Views:
    2,183
    Hessam
    Aug 8, 2003
  2. minlearn
    Replies:
    2
    Views:
    460
    red floyd
    Mar 13, 2009
  3. Daniel Thoma
    Replies:
    12
    Views:
    1,962
    markspace
    Jul 31, 2009
  4. Hessam
    Replies:
    1
    Views:
    236
    Teemu Keiski
    Aug 16, 2003
  5. Hessam
    Replies:
    0
    Views:
    270
    Hessam
    Aug 8, 2003
Loading...

Share This Page