Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / June 2006

Tip: Looking for answers? Try searching our database.

Java generic issue in array

Thread view: 
jacksu - 25 May 2006 20:58 GMT
I could create:

ArrayList<Node> myarr = new ArrayList<Node>();

but can't

ArrayList<Node> myarr[] =  new ArrayList<Node>[n];
I got error "Cannot create a generic array of ArrayList<Node>

any suggsetion?

Thanks.
nkalagarla@gmail.com - 25 May 2006 21:50 GMT
generic array creation is not allowed.Try following work-around.

ArrayList<Node>[] myarr = (ArrayList<Node>[])
Array.newInstance(ArrayList.class,n);

> I could create:
>
[quoted text clipped - 8 lines]
>
> Thanks.
Luc The Perverse - 25 May 2006 22:02 GMT
> generic array creation is not allowed.Try following work-around.
>
> ArrayList<Node>[] myarr = (ArrayList<Node>[])
> Array.newInstance(ArrayList.class,n);

Eh?

What in the world is that?

I think the more common way is (at least what I have seen):

Where n is some integer:

ArrayList<Node>[] myarr = new ArrayList[n];
for(int i=0;i<n;i++)
    myarr[i] = new ArrayList<Node>(); //initialize each individually

--
LTP

:)
nkalagarla@gmail.com - 25 May 2006 22:29 GMT
Well, with my approach you won't get any warning.  With yours, you will
see one warning and to suppress it you have to specify
@SuppressWarnings("unchecked") annotation.

:)
Chris Smith - 25 May 2006 22:52 GMT
> Well, with my approach you won't get any warning.  With yours, you will
> see one warning and to suppress it you have to specify
> @SuppressWarnings("unchecked") annotation.
>
> :)

Didn't you mean that the other way around?  Casting from Object (the
return type of Array.newInstance) to ArrayList<Node>[] ought to result
in an unchecked cast warning.  Nothing in Luc's response seemed to
require this warning.

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

Mike Schilling - 25 May 2006 23:17 GMT
>> Well, with my approach you won't get any warning.  With yours, you will
>> see one warning and to suppress it you have to specify
[quoted text clipped - 6 lines]
> in an unchecked cast warning.  Nothing in Luc's response seemed to
> require this warning.

Luc's

   ArrayList<Node>[] myarr = new ArrayList[n];

causes a warning:

Warnings.java:8: warning: [unchecked] unchecked conversion
found   : java.util.ArrayList[]
required: java.util.ArrayList<java.lang.String>[]
       ArrayList<String>[] myarr = new ArrayList[12];
Chris Smith - 25 May 2006 23:39 GMT
> ArrayList<Node>[] myarr = new ArrayList[n];

Yep, you're right.  I picked up that confusion from an early version of
the Eclipse generics compiler.  It appears that nkalagarla also did the
same, since the warning from his/her post was apparently missing in
Eclipse up to 3.2M6, and fixed there.  With the current 3.2 milestone,
both options correctly give warnings.

That'll teach me to read the spec before replying with something I don't
understand. :)

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

Mike Schilling - 28 May 2006 06:03 GMT
>> ArrayList<Node>[] myarr = new ArrayList[n];
>
[quoted text clipped - 6 lines]
> That'll teach me to read the spec before replying with something I don't
> understand. :)

If you're implying that you'd understand it after you read the spec, it must
be a better-written spec than the ones I've seen.
Chris Smith - 28 May 2006 15:37 GMT
> If you're implying that you'd understand it after you read the spec, it must
> be a better-written spec than the ones I've seen.

Well, no, but understanding specs is not impossible -- just an acquired
skill.  I would have said "yes" until the third edition came out.  
Generics, though, complicate the specification even more than the
language.

Here's what I'm seeing here doesn't lead to the conclusion I expected,
though.  Perhaps someone can clarify.  The expression in question was:

   ArrayList<Node>[] arr = new ArrayList[n];

Eclipse and javac both compile this but give a warning about unchecked
conversion.

5.2 (Assignment Conversion) says that we have two options for the
assignment conversion.  We should apply (among other irrelevant things)
widening reference conversion to convert the type ArrayList[] to
ArrayList<Node>[] first.  If that's not possible, we should apply
unchecked conversion to do so.

5.1.5 (Widening Reference Conversions) says that widening primitive
conversion is only possible if the type ArrayList[] is a subtype of
ArrayList<Node>[].

4.10.3 (Subtyping among Array Types) says that ArrayList[] is a subtype
of ArrayList<Node>[] if and only if ArrayList is a subtype of
ArrayList[].

4.10.2 (Subtyping among Class and Interface Types) says that
ArrayList<Node> is a subtype of ArrayList, but NOT vice versa.  So we've
failed.

Back to 5.2 (Assignment Conversion), the next option is to apply
unchecked conversion from ArrayList[] to ArrayList<Node>[].  This only
applies if ArrayList[] is a raw type.

4.8 (Raw Types) makes ArrayList[] NOT a raw type, even though its
component type is a raw type.  Therefore we can't apply unchecked
conversion.

So it seems that the code above should actually fail to compile.  Yet it
does compile.  To make that correct, it would seem that it would be
necessary to expand the definition of unchecked conversion in 5.1.9 to
include the rule that if an unchecked conversion exists from T to S,
then an unchecked conversion exists from T[] to S[], and then to update
text in sections like 5.2 to remove the requirement (which is
unnecessary anyway) that unchecked conversion is only applied to raw
types.

Anyone disagree?  What am I missing?

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

Mike Schilling - 28 May 2006 17:36 GMT
>> If you're implying that you'd understand it after you read the spec, it
>> must
[quoted text clipped - 4 lines]
> Generics, though, complicate the specification even more than the
> language.

Exactly my point.  The second edition has some complications (the worst I
can recall offhand being the rules for resolving method overloads), but they
can be mastered with a bit of study.  This remains true for the 1.5
additions to the language other than generics.  Geenrics are explained in a
way that does not answer a large number of questions, which then have to be
resolved by trying things and wondering if javac implements the spec
correctly.
Tony Morris - 30 May 2006 23:40 GMT
> Exactly my point.  The second edition has some complications (the worst I
> can recall offhand being the rules for resolving method overloads), but
> they can be mastered with a bit of study.  This remains true for the 1.5
> additions to the language other than generics.

This particular rule changed three times since JDK 1.5.0 beta and once after
JLS 3e draft was released.

Signature

Tony Morris
http://tmorris.net/

Mike Schilling - 30 May 2006 23:58 GMT
>> Exactly my point.  The second edition has some complications (the worst I
>> can recall offhand being the rules for resolving method overloads), but
[quoted text clipped - 3 lines]
> This particular rule changed three times since JDK 1.5.0 beta and once
> after JLS 3e draft was released.

Sorry, which rule was that?  If it's resolving method overloads with the
added complication of generics, I'm sure the result is horrific.

Pre-generics overload resolution seems to have changed something during 1.4.
It originally took the return type of an individual overload into account,
but ceased to do so.
Dale King - 30 May 2006 15:02 GMT
>> If you're implying that you'd understand it after you read the spec, it must
>> be a better-written spec than the ones I've seen.
[quoted text clipped - 46 lines]
> unnecessary anyway) that unchecked conversion is only applied to raw
> types.

I think the problem is that last step where you say that ArrayList[] is
not a raw type.

4.8 says:

"To facilitate interfacing with non-generic legacy code, it is also
possible to use as a type the erasure (§4.6) of a parameterized type
(§4.5). Such a type is called a raw type."

4.6 on type erasure says: "The erasure of an array type T[] is |T|[]".
Where |T| means the erasure of T.

So ArrayList[] is a type erasure of ArrayList< T >[] and a raw type.

I think the confusion may be the use of the word "name" in section 4.8.
In reality ArrayList[] is "the name of a generic type declaration used
without any accompanying actual type parameters".

Signature

 Dale King

Chris Smith - 30 May 2006 17:07 GMT
> > 4.8 (Raw Types) makes ArrayList[] NOT a raw type, even though its
> > component type is a raw type.  Therefore we can't apply unchecked
> > conversion.

> I think the problem is that last step where you say that ArrayList[] is
> not a raw type.
[quoted text clipped - 4 lines]
> possible to use as a type the erasure (§4.6) of a parameterized type
> (§4.5). Such a type is called a raw type."

Hmm.

I agree that ArrayList[] is the type erasure of ArrayList<Node>[].  
However, I don't agree that ArrayList[] is "the erasure of a
parameterized type" since ArrayList<Node>[] is not a parameterized type.  
§4.5 defines a parameterized type, and it doesn't include arrays whose
component type is a parameterized type.

Signature

www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

Dale King - 31 May 2006 01:24 GMT
>>> 4.8 (Raw Types) makes ArrayList[] NOT a raw type, even though its
>>> component type is a raw type.  Therefore we can't apply unchecked
[quoted text clipped - 16 lines]
> §4.5 defines a parameterized type, and it doesn't include arrays whose
> component type is a parameterized type.

I certainly agree that section 4.5 still needs lots of work. It seems
very much a work in progress which is apparent by all the discussion
sections. But I think it is a stretch to say that ArrayList<Node>[] is
not a parameterized type. It is quite obviously a parameterized type.

I note that in 4.3 it says that an array is a reference type and
"Reference types may be parameterized (§4.5) with type arguments (§4.4)".

I went to see if this has been cleared up for 1.6, but the docs for 1.6
point to the old pre-generic JLS.

The 3rd edition of the JLS is supposedly not published yet and there is
a feedback form on the website, so you might want to feed back that they
need to be more precise.

Signature

 Dale King

Chris Smith - 31 May 2006 06:40 GMT
> I certainly agree that section 4.5 still needs lots of work. It seems
> very much a work in progress which is apparent by all the discussion
> sections. But I think it is a stretch to say that ArrayList<Node>[] is
> not a parameterized type. It is quite obviously a parameterized type.

It's certainly not "obviously" a parameterized type.  Perhaps you're
right that it's intended to be one, but on several readings I still
can't find an interpretation that makes ArrayList<Node>[] fit that
definition of a parameterized type.  It's actually rather obvious to me
that it is, in fact, NOT a parameterized type.  You may disagree, but
it's certainly not a stretch, and it's certainly far from obvious in the
other direction.

> I note that in 4.3 it says that an array is a reference type and
> "Reference types may be parameterized (§4.5) with type arguments (§4.4)".

That's interesting, to be sure.  I'm not sure what to think of it.  It's
certainly written to imply that all three kinds of types may have
arguments, and yet the snippets of grammar right below say very clearly
otherwise.

In the end, though, the type is not ArrayList[]<Node> (which would be
illegal anyway), but rather ArrayList<Node>[].  In other words, it
doesn't have type arguments.  We could surmise that the JLS is using
some kind of strange terminology that a type "has type arguments" if
there are type arguments anywhere lexically inside the definition of the
type, but that wouldn't be a very useful sort of terminology.  Rather,
it appears that the statement you quoted is true, but a stronger
statement -- "All reference types may be parameterized with type
arguments" -- is not true.  In particular, array types never have type
parameters.

In either case, 4.5 is very specific: a parameterized type is a class or
interface name, and then a list of type parameters.  No arrays are
possible, whether are not arrays are also considered to have type
parameters.

> The 3rd edition of the JLS is supposedly not published yet and there is
> a feedback form on the website, so you might want to feed back that they
> need to be more precise.

I have a print copy of the JLS 3rd edition, so it is published at least
under the common definition of that term.  If it's still tentative,
that's interesting.  I haven't seen anything like that.

Signature

Chris Smith

Mike Schilling - 31 May 2006 08:26 GMT
>> The 3rd edition of the JLS is supposedly not published yet and there is
>> a feedback form on the website, so you might want to feed back that they
>>  need to be more precise.

> I have a print copy of the JLS 3rd edition, so it is published at least
> under the common definition of that term.  If it's still tentative,
> that's interesting.  I haven't seen anything like that.

I have it as well.  It's not labeled "rough draft" but it certainly reads
like one..
Dale King - 31 May 2006 15:44 GMT
> In either case, 4.5 is very specific: a parameterized type is a class or
> interface name, and then a list of type parameters.  No arrays are
> possible, whether are not arrays are also considered to have type
> parameters.

I did some more reading and think perhaps it is not a question of
whether it is parameterized, but whether it is reifiable. And I must say
that the reifiable discussion is very fuzzy to me. They have a section
in chapter 4 on it, but the word is not even used in chapter 5.

The question is whether you consider ArrayList[] to be a raw type. 4.8
says a raw type is "The name of a generic type declaration used without
any accompanying actual type parameters." I think that would be
applicable. This gives us a path through section 5.2 (identity
conversion followed by unchecked conversion because it is a raw type).

At the end of chapter 10 on arrays in the section on the runtime
ArrayStoreException it has a discussion section that says:

"If the element type of an array were not reifiable (§4.7), the virtual
machine could not perform the store check described in the preceding
paragraph. This is why creation of arrays of non-reifiable types is
forbidden. One may declare variables of array types whose element type
is not reifiable, but any attempt to assign them a value will give rise
to an unchecked warning (§5.1.9)."

According to 4.7 ArrayList<Node>[] is not reifiable and so any attempt
to assign to it should give the unchecked warning. It would be nice if
this information were incorporated into section 5.1.9.

>> The 3rd edition of the JLS is supposedly not published yet and there is
>> a feedback form on the website, so you might want to feed back that they
[quoted text clipped - 3 lines]
> under the common definition of that term.  If it's still tentative,
> that's interesting.  I haven't seen anything like that.

I'm just going by what the website said. I see now that it is just out
of date information since it says "the physical book should be available
in June 2005."

It would still be a good idea to provide feedback that they might add
some errata or clarification.

Signature

 Dale King

Chris Smith - 01 Jun 2006 18:24 GMT
> I did some more reading and think perhaps it is not a question of
> whether it is parameterized, but whether it is reifiable. And I must say
[quoted text clipped - 6 lines]
> applicable. This gives us a path through section 5.2 (identity
> conversion followed by unchecked conversion because it is a raw type).

Yes, it would.  I was using the earlier definition from the previous
sentence ("type erasure of a parameterized type").  The spec claims that
this second definition is more precise; I disagree, since I don't see
any clear definition of what constitutes a generic type declaration.  
However, for the sake of discussion and because implementations seem to
support it, we'll adopt your view that ArrayList[] is the name of a
generic type declaration.  Still, unchecked conversion (5.1.9) presents
a problem, since the target of unchecked conversion is a parameterized
type, and I previously explained why I don't think that
ArrayList<Node>[] is a parameterized type.

> At the end of chapter 10 on arrays in the section on the runtime
> ArrayStoreException it has a discussion section that says:
[quoted text clipped - 5 lines]
> is not reifiable, but any attempt to assign them a value will give rise
> to an unchecked warning (§5.1.9)."

Yes, so this seems to say that 5.1.9 ought to apply to conversion of
array types.  I believe this is an internal contradiction within the
language specification.  There is no way to reconcile the above
statement with the definition of unchecked conversion in 5.9 and the
definition of a parameterized type in 4.5.  Although the section you
quote is non-normative, it still indicates a problem in that the actual
consequences of the language spec conflict not only with existing
implementations, but also with the clearly stated intent of the
specification itself.

> It would still be a good idea to provide feedback that they might add
> some errata or clarification.

Yes, I agree.

Signature

Chris Smith - Lead Software Developer / Technical Trainer
MindIQ Corporation

Dale King - 02 Jun 2006 15:00 GMT
>> I did some more reading and think perhaps it is not a question of
>> whether it is parameterized, but whether it is reifiable. And I must say
[quoted text clipped - 37 lines]
> implementations, but also with the clearly stated intent of the
> specification itself.

Then I think we are in agreement. It is clear from the JLS that the
assignment should be allowed, but the JLS is not being precise enough
for a language lawyer and could definitely be cleaned up and made more
explicit.

Signature

 Dale King

Chris Smith - 02 Jun 2006 19:26 GMT
> Then I think we are in agreement. It is clear from the JLS that the
> assignment should be allowed, but the JLS is not being precise enough
> for a language lawyer and could definitely be cleaned up and made more
> explicit.

Yes, in a way.  I'd add the caveat that the only thing that convinces me
that allowing the assignment is intended to be legal is the non-
normative "Discussion" section at the end of chapter 10... that and the
behavior of the current implementation.  I think I'd use the word "fix"
rather than "clean up."

Signature

Chris Smith - Lead Software Developer / Technical Trainer
MindIQ Corporation

Mike Schilling - 02 Jun 2006 20:50 GMT
>> Then I think we are in agreement. It is clear from the JLS that the
>> assignment should be allowed, but the JLS is not being precise enough
[quoted text clipped - 5 lines]
> normative "Discussion" section at the end of chapter 10... that and the
> behavior of the current implementation.

And that, naively, you'd expect it be allowed (or I would, anyway.)  There's
a lot to be said for Least Astonishment.
Tony Morris - 26 May 2006 02:17 GMT
>I could create:
>
[quoted text clipped - 8 lines]
>
> Thanks.

You cannot do that.
Ponder the thought: you cannot write a 1.5 java.util.ArrayList
implementation without generating a compile-time warning. Some say generics
are broken, others (fewer) say arrays are broken - it's all guff on top of a
flawed premise though.

Signature

Tony Morris
http://tmorris.net/

Mike Schilling - 26 May 2006 19:07 GMT
> Ponder the thought: you cannot write a 1.5 java.util.ArrayList
> implementation without generating a compile-time warning. Some say
> generics are broken, others (fewer) say arrays are broken - it's all guff
> on top of a flawed premise though.

Nitpick: you can do it in later versions of 1.5 by using an annotation that
specifically turns that warning off.   Only a slight improvement, I agree.
Thomas Hawtin - 26 May 2006 10:24 GMT
> I could create:
>
[quoted text clipped - 4 lines]
> ArrayList<Node> myarr[] =  new ArrayList<Node>[n];
> I got error "Cannot create a generic array of ArrayList<Node>

Don't use arrays of references...

Instead use:

    List<List<Node>> nodeLists = new ArrayList<List<node>>();

IIRC, the Joshua Bloch's Effective Java Reloaded session at JavaONE
covered that sort of thing. </appeal-to-authority>

Alternatively add a class for the concept of the particular use of a
List of Nodes:

class NodeString {
    private final List<Node> nodes;
}
...
    List<NodeString> nodeStrings = new ArrayList<NodeString>();

Tom Hawtin
Signature

Unemployed English Java programmer
http://jroller.com/page/tackline/



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.