Making array classes

T

Tom Anderson

If i have a class, is there some way i can make a class for the
corresponding array? To clarify, i'm after an implementation for:

void makeArrayClass( Class cl )

Such that

makeArrayClass( cl ).getComponentType().equals( cl )

So that i can do, for example:

import java.lang.reflect.Array ;
void example( Class cl )
{
Class arrayCl = makeArrayClass( cl ) ;
Object[][] array = (Object[][])Array.newInstance( arrayCl, 3 ) ;
array[0] = Array.newInstance( cl, 3 ) ;
array[0][0] = cl.newInstance()
}

My end goal is to make arrays of arbitrary dimension and size (and they
may be ragged, so i can't use Array.newInstance(Class,int[])).

I've poked about in Class and Array, but can't see anything.

TIA and hello to all,
tom
 
W

Wolfram Rittmeyer

Tom said:
If i have a class, is there some way i can make a class for the
corresponding array? To clarify, i'm after an implementation for:

void makeArrayClass( Class cl )

Such that

makeArrayClass( cl ).getComponentType().equals( cl )

So that i can do, for example:

import java.lang.reflect.Array ;
void example( Class cl )
{
Class arrayCl = makeArrayClass( cl ) ;
Object[][] array = (Object[][])Array.newInstance( arrayCl, 3 ) ;
array[0] = Array.newInstance( cl, 3 ) ;
array[0][0] = cl.newInstance()
}

My end goal is to make arrays of arbitrary dimension and size (and they
may be ragged, so i can't use Array.newInstance(Class,int[])).

I've poked about in Class and Array, but can't see anything.

TIA and hello to all,
tom

No, there's not. You can construct an Object-array and pass your objects
into it, but that's not typesafe. With generics of JDK 1.5 you should be
able to do something like that, but that's most probably not released
before June 2004. BTW: are you sure that ArrayList or something similar
does not fit your needs better (problem with type-safety remains though)?
 
T

Tom Anderson

Incidentally, the two hacks i've thought of (but not tested) so far are:

- Munge the class name; for class Foo, "[LFoo;" is its array class,
"[[LFoo;" its array-of-array class, etc. You can pass these strings to
Class.forName to get the actual class objects.

- Abuse java.lang.reflect.Array's newInstance(Class,int[]) method; by
passing in the base class, then an array of the right length with zeroes
in all but the first place, you can make an array of the right type
which happens to be filled with zero-length arrays (rather than the
nulls you'd get if you constructed it directly).
No, there's not.
Curses!

You can construct an Object-array and pass your objects into it, but
that's not typesafe. With generics of JDK 1.5 you should be able to do
something like that, but that's most probably not released before June
2004.

Tiger's generics are only skin-deep: they're handled by type erasure,
which means you can't do:

<T> T[] f()
{
return new T[3] ;
}

Or if you can, what you actually get is an Object[] decorated to look like
a T[].
BTW: are you sure that ArrayList or something similar does not fit your
needs better (problem with type-safety remains though)?

I'm afraid nothing less than real live arrays will do; i'm writing some
generic quasi-reflective code for [de]serializing objects (purely for my
own amusement and education), and it has to be able to handle client code
throwing more or less arbitrary objects, including ragged multidimensional
arrays, at it.

tom
 
T

Tom Anderson

(1) Array classes describe the component type and number of dimensions,
but not the size of any dimension. (I think the OP already realized this.)

Indeed i did.
(2) An array class constructed with an array-type component A and n
dimensions is the same as the class with the component type of A and n +
(dumber of A's dimensions) dimensions. [Apply recursively if you like.]

(3) If you don't know the component type and/or number of dimensions at
compile-time then any such class or object you construct will have to be
handled either generically or reflectively.

With those in mind, one way to proceed is to construct the array you
want from the bottom up: take the base objects and assemble them into 1D
arrays in whatever arrangement you want, using Array.newInstance(Class,
int); then take the 1D arrays and assemble them into 1D arrays, again
using Array.newInstance(Class, int), resulting in 2D arrays or the base
component type; continue in the same vein until you have one n-D array
containing everything. You can make an array of arbitrary base
component type and arbitrary shape (subject to VM limits) in this way.

Sadly, that scheme won't work for me - i really need to have the outer
arrays first, to put the inner arrays into. Well, i could change my code
to work that way round, but i'd rather not if i can avoid it.

However, your idea of recursively building up the type is quite cunning; i
can write makeArrayClass like this:

Class makeArrayClass( Class base, int dims )
{
Class cl = base ;
for (int i = 0 ; i < (dims - 1) ; ++i)
{
cl = Array.newInstance( base, 0 ).getClass() ;
}
return cl ;
}

And then pass the result into Array.newInstance to get the real thing.

Better yet, i can start off by building myself a little stash of array
classes like Russian dolls, so i don't have to repeat the computation at
every level.

Anyway, it seems that There Is More Than One Way To Do It. How perfectly
disgusting!

Thanks for your help.

tom
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top