Creating arrays using GENERICS

I

IveCal

Hi all,


Please help again. I need to resolve this issue. Why is this code not
allowed:

Gen<Integer> intGen[] = new Gen<Integer>[10];

According to the book I read by Schildt: "Arrays of specific generic
types simply aren't allowed, because they can lead to a loss of type
safety."

I understand what type safety means but I dont get in what WAY does
type safety compromised in THIS SITUATION.

Java experts please do help.


Best Regards,
Ive
 
L

Lew

IveCal said:
Please help again. I need to resolve this issue. Why is this code not
allowed:

Gen<Integer> intGen[] = new Gen<Integer>[10];

According to the book I read by Schildt: "Arrays of specific generic
types simply aren't allowed, because they can lead to a loss of type
safety."

I understand what type safety means but I dont get in what WAY does
type safety compromised in THIS SITUATION.

Java experts please do help.

I'm not claiming to be an expert, but I'll sound like one by quoting the Java
Language Specification (JLS):
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).
<http://java.sun.com/docs/books/jls/third_edition/html/arrays.html#10.10>

More specifically, in ss. 15.10:
An array creation expression creates an object that is a new array
whose elements are of the type specified by the PrimitiveType or
ClassOrInterfaceType. It is a compile-time error if the
ClassOrInterfaceType does not denote a reifiable type (§4.7).
Otherwise, the ClassOrInterfaceType may name any named reference
type, even an abstract class type (§8.1.1.1) or an interface type (§9).

Discussion

The rules above imply that the element type in an array creation
expression cannot be a parameterized type, other than an unbounded wildcard.
<http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.10>
 
I

IveCal

IveCal said:
Please help again. I need to resolve this issue. Why is this code not
allowed:
Gen<Integer> intGen[] = new Gen<Integer>[10];
According to the book I read by Schildt: "Arrays of specific generic
types simply aren't allowed, because they can lead to a loss of type
safety."
I understand what type safety means but I dont get in what WAY does
type safety compromised in THIS SITUATION.
Java experts please do help.

I'm not claiming to be an expert, but I'll sound like one by quoting the Java
Language Specification (JLS):
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).

<http://java.sun.com/docs/books/jls/third_edition/html/arrays.html#10.10>

More specifically, in ss. 15.10:> An array creation expression creates an object that is a new array
whose elements are of the type specified by the PrimitiveType or
ClassOrInterfaceType. It is a compile-time error if the
ClassOrInterfaceType does not denote a reifiable type (§4.7).
Otherwise, the ClassOrInterfaceType may name any named reference
type, even an abstract class type (§8.1.1.1) or an interface type (§9).

The rules above imply that the element type in an array creation
expression cannot be a parameterized type, other than an unbounded wildcard.

<http://java.sun.com/docs/books/jls/third_edition/html/expressions.htm...>

Hi Lew,


I'll go over the link provided. It's very technical.
Anyway, thank you very much for the help.


Regards,
Ive
 
C

Curt Welch

IveCal said:
Hi all,

Please help again. I need to resolve this issue. Why is this code not
allowed:

Gen<Integer> intGen[] = new Gen<Integer>[10];

According to the book I read by Schildt: "Arrays of specific generic
types simply aren't allowed, because they can lead to a loss of type
safety."

I understand what type safety means but I dont get in what WAY does
type safety compromised in THIS SITUATION.

My longer discussion is below. This is all new to me, but from my reading
tonight, and my testing, I can't find any reason to explain why it's not
allowed or why it's not safe.

new Gen<Integer>[10]

is just not allowed by the compiler but I don't have a clue why they choose
to reject that.

However you can do this:

Gen<Integer> intGen[] = new Gen[10];

It will produce an unchecked warning, which you can just ignore. It will
still do full generic checks on everything you do with intGen and on
everything you put into or take out of the array as far as I can tell.

As far as I can tell, doing the above, will make your code safer, than not
using generics and just defining it like this:

Gen intGen[] = new Gen[10];
Java experts please do help.

I'm no expert BTW, I'm just learning Java.
Best Regards,
Ive

This has been an interesting learning experience for me. Generics are
still such a mystery to me when you get down to these sorts of odds
problems.

I spent a few hours reading multiple pages on this and I can't for the life
of me figure out why that isn't allowed in Java. All the pages I've read
simply translate to "it's not allowed" and none of them really explain why
it's not allowed to my satisfaction.

Generics are a compile time feature, and not a run time feature as I
understand it. And I don't see why the same rules used at compile time for
generic objects can't also be used for generic arrays.

Playing with some test code, I discovered that you can in fact use generics
for Arrays for the most part. While you can't do this:

List<Integer> li[] = new ArrayList<Integer>[10];

You can do this:

List<Integer> li[] = new ArrayList[10];

It will produce an unchecked warning, but it will compile. Not only that,
but when you use the array variable li, and when you try to use li[n], it
will, as far as I can tell, correctly honor all the normal generic
restrictions.

For example, if you try this:

List<Number> ln[];

ln = li;

It will produce a compile error as you would want it to where as without
the generic definitions, it would of course have allowed it.

And if you try this:

li[0].add("string");

It will produce a compile as expected based on the generic definition of
li.

So as far as I can see, everything I tested with generic arrays works as
expected. You get compile errors if you try to do something that's a
violation of the generic definition of the array.

The only thing I've found that doesn't work, is the new statement, and I
don't understand why they choose to make everything else work, and not
allow you to use a generic new statement. So as far as I can see, you can
use generics with arrays, and the compiler does do all the checking for
you, but the only real drawback, is that you are forced to live with
unchecked exception warnings when you create the array.

I'm sure there's something I'm missing, but I don't know what it is yet.

Part of it might be the fact that arrays already have run-time support for
type checking. Arrays are in effect collection objects already, but unlike
the normal collection objects, Java included run time type checking of
arrays. That is, arrays know what type of object can be stored in them,
and will throw a ArrayStoreException at run time if you try to put the
wrong thing in them:

String[] sa = new String[10];

// acts much like: Array<String> sa = new Array<String>(10);
// so in effect, arrays are a limited form of generics already.

Object oa[] = sa; // Generics would reject this, but java allows
it

oa[0] = new Object(); // compiles fine, but throws
ArrayStoreException

// the jvm won't let you put an object into a string array even without
// generics.

So at run time, the string array "knows" it's a string array and will throw
an exception if you make an error. In effect, Arrays already have
generic-like type safety built into at run time.

Generics were added for the purpose of adding safety to the Collection
objects which before Generics had no compile time checks at all.

So I wonder if the Java designers simply didn't think of making Generics
work for Arrays since they are such a different beast to start with and
since arrays already have their own version of type safety done a different
way. Maybe they were thinking that to add generics to arrays, they would
have to extend the run time check system of arrays to support full generic
types, and since they didn't plan to make run time changes to support
generics, they say it as something they just couldn't add to arrays? But
from what I understand, I don't see why that is true because I don't
understand why all the same compile time rules used for generic objects
can't be correctly applied to generic arrays - and as I saw in my testing,
it seems the compiler is actually correctly applying those compile time
rules to generic arrays.

It's all very interesting and mystical still to me. But, the end result,
is that you can define, and use, generic arrays, you just can't create them
without a compile error - you have to create them as non generic arrays and
live with the compile time warning when you assign them to the generic
array variable. I can't believe it is any less safe to do that than to not
use a generic definition of the array.

However, if you want compile time generic safety for Arrays, it seems to me
the best solution is to not use arrays, and just use an ArrayList (or other
collection object) instead.
 
H

Hendrik Maryns

IveCal schreef:
Hi all,


Please help again. I need to resolve this issue. Why is this code not
allowed:

Gen<Integer> intGen[] = new Gen<Integer>[10];

According to the book I read by Schildt: "Arrays of specific generic
types simply aren't allowed, because they can lead to a loss of type
safety."

I understand what type safety means but I dont get in what WAY does
type safety compromised in THIS SITUATION.

Did you read http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf? It
is in there.

Short answer: do not mix arrays and generics, use lists instead.

H.
--
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
http://aouw.org
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.4-svn0 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iD8DBQFHQsmve+7xMGD3itQRAgrvAJ0SZQqbarlgHBjMG2qyAyqLDsKm4wCcDxqr
jrEHUf2j0g+pWonbL7kObk8=
=8DCr
-----END PGP SIGNATURE-----
 

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

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top