Generic Array Creation

  • Thread starter Marc van Dongen
  • Start date
M

Marc van Dongen

Dear all,


I'd very much appreciate if somebody could provide a pointer on how to
do the following.

I've defined a generic interface MyInterface<T> and several classes
that implement this interface. I'd like to create an array the members
of which can be assigned any object belonging to a class that
implements the interface.

I know that an Object array would solve the problem of assigning
objects from different classes. However, this is not very clean as I'd
lose type information and I'd have to cast each time I get something
from the array.

I've considered java.lang.reflect.Array.newInstance( Class C, int
size ) but this requires a single class C and I'd end up with an
array which only allows me assignments of C subclass objects.

Ideally, I'd like to declare the array as follows: MyInterface<Type>[]
array, for a specific raw type.

Is there a way to do this?

Thanks in advance for your help.

Regards,


Marc van Donge
 
J

John B. Matthews

[...]
I'd very much appreciate if somebody could provide a pointer on how
to do the following.

I've defined a generic interface MyInterface<T> and several classes
that implement this interface. I'd like to create an array the
members of which can be assigned any object belonging to a class that
implements the interface.

I know that an Object array would solve the problem of assigning
objects from different classes. However, this is not very clean as
I'd lose type information and I'd have to cast each time I get
something from the array.

I've considered java.lang.reflect.Array.newInstance( Class C, int
size ) but this requires a single class C and I'd end up with an
array which only allows me assignments of C subclass objects.

Ideally, I'd like to declare the array as follows:
MyInterface<Type>[] array, for a specific raw type.

Is there a way to do this?

In chapter 5, item 25, of _Effective_Java_, Joshua Bloch discusses why
this is not type safe:

<http://java.sun.com/docs/books/effective/>

Subsequent items suggest alternatives.
 
A

Andreas Leitgeb

Marc van Dongen said:
I've defined a generic interface MyInterface<T> and several classes
that implement this interface. I'd like to create an array the members
of which can be assigned any object belonging to a class that
implements the interface.

arrays and generics do not work together with current versions of Java
(for any sufficiently interesting definition of "work together")

You can only define arrays for non-generic types, and do casts
in all the accessors.
 
M

Mark Space

Marc said:
Ideally, I'd like to declare the array as follows: MyInterface<Type>[]
array, for a specific raw type.

Is there a way to do this?

Syntactically this works:

List<?>[] listA = new ArrayList<?>[3];

Which is basically the same that you'd get at runtime anyway. If you
need to do things with this array, it might help if we new what those
things were....
 
M

Marc van Dongen

According to Marc van Dongen  <[email protected]>:

[ Generic Arrays ]
Type parameters exist only at compile-time. At runtime, the array
instance will "know" that it is an array of "MyInterface", but it cannot
know anything like "MyInterface<Type>". What you can do is the following:

   MyInterface<? extends Type>[] t = new MyInterface[n];

Thanks. This comment actually made me find a solution which I hadn't
thought of. When I tried it it worked straight away. I hadn't thought
of (1) declaring an array of an unparameterised type MyInterfaces,
filling it, and then casting it to a parameterised type. This solution
is quite acceptable to me as the cast is the only one in my program.

[more stuff]

Thanks.
    MyInterface[] t = new MyInterface[n];
    Object[] u = t;
    u[0] = "Hello World!";

Thanks. I'm aware of this and it won't happen. The array is filled
once and remains fixed. That's why I prefer using arrays to a generic
list type. I had tried the generic list route but it is *much* (IIRC
4-5 times) slower.
A last note on the compiler "guarantee": as you see, the warning warns
you about a runtime ClassCastException which may happen, but not
necessarily in the same class. The compiler guarantee is complete only
if you compiled _all_ the classes comprising your application (and it
can be fooled nonetheless with reflection).

I compiled all classes, got no errors and only one warning.

[use native code]

Thanks very much for your detailed answer. It helped me solve the
problem.

Regards,


Marc van Dongen
 
M

Marc van Dongen

On Feb 5, 2:10 pm, Andreas Leitgeb <[email protected]>
wrote:

[ Generic Arrays ]
arrays and generics do not work together with current versions of Java
(for any sufficiently interesting definition of "work together")

You can only define arrays for non-generic types, and do casts
in all the accessors.

Thanks.

Regards,


Marc van Dongen
 
M

Marc van Dongen

[Generic Array Creation]
Syntactically this works:

   List<?>[] listA = new ArrayList<?>[3];

Thanks. I'm not sure if I understand you point. If you're suggesting I
should use lists, then I could but they're too slow for me.
Which is basically the same that you'd get at runtime anyway. If you
need to do things with this array, it might help if we new what those
things were....

Reading only.

Regards,


Marc van Dongen
 
M

Mark Space

Marc said:
[Generic Array Creation]
Syntactically this works:

List<?>[] listA = new ArrayList<?>[3];

Thanks. I'm not sure if I understand you point. If you're suggesting I
should use lists, then I could but they're too slow for me.

No I'm using List because it's an interface that everybody has and has
access to. You can substitute "MyInterface" for "List" and "ArrayList"
up there and it will work the same.
 
L

Lew

Marc said:
According to Marc van Dongen <[email protected]>:

[ Generic Arrays ]
Type parameters exist only at compile-time. At runtime, the array
instance will "know" that it is an array of "MyInterface", but it cannot
know anything like "MyInterface<Type>". What you can do is the following:

MyInterface<? extends Type>[] t = new MyInterface[n];

Thanks. This comment actually made me find a solution which I hadn't
thought of. When I tried it it worked straight away. I hadn't thought
of (1) declaring an array of an unparameterised type MyInterfaces,
filling it, and then casting it to a parameterised type. This solution
is quite acceptable to me as the cast is the only one in my program.

Make sure you follow the guidelines from /Effective Java/, referenced
upthread, with respect to use of '@SuppressWarnings( "unchecked" )'.
 

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,968
Messages
2,570,149
Members
46,695
Latest member
StanleyDri

Latest Threads

Top