creating array of generic object

hello, what i want to do is something like:

publicclass AClass<Kextends SomeObject>{

SomeObject[] AnArray;

publicvoid amethod(){

AnArray=new K[10];

}

}

So I want to create an array of some kind of object at runtime without already know the kind of the object. The thing is that I think that generics are only "known" at compiling time, so this AnArray=new K[10];

is propably completely wrong but I cannot think of any other way of creating an array without knowing in advance the kind of object....So if someone could enlighten me on how to do this...

if this is of any help the reason i want to have such implementation is that this array is supposed to be a hashmap and the SomeObject is supposed to be a super class of some different kind of LinkedList classes, so I want the hashmap to be flexible on what kind of list will be used. Suggestions for completely different approach are also welcome offcourse, but I would prefer it if someone could give some brief explaination on how manipulating such a generic array issue...

[1435 byte] By [fraksiaa] at [2007-11-15]
# 1

actually on second thought:

AnArray=new K[10];

doesnt look really wrong, as the generic information that is lost in runtime is the parameters of parametrized types, but the parameter of the class,here K, I supose, and correct me if I'm wrong, that at the time of the instantiation is exactly the object that is passed to the generic class. Meaning that if I do:

AClass<SomeObject> aclass=new AClass<SomeObject>();

from then on K is a SomeObject...

fraksiaa at 2007-7-12 > top of java,Core,Core APIs...
# 2

Hi Fraksia,

Unfortunately, array creation of type parameters is not allowed, so you can't

say new T[3]; That is because T doesn't exist at compile time. It is erased.

It is misleading - I know. Because when you say

AClass<SomeObject> aclass=new AClass<SomeObject>();

you might thing that T becomes SomeObject in your class wheres

what that does is that whenever you expect your type parameter in

the calling code, compiler will insert a cast. See the example below:

class MyClass<T> {

T o;

public MyClass(T o) {

this.o=o;

}

public T get() {

return o;

}

}

class CallingClass {

public static void main(String[] args) {

MyClass<String> m=new MyClass<String>("Test");

String o=m.get(); //no cast needed here

}

}

Benefit: increased type safety, no casts needed in the CallingClass.

What really happens is:

class MyClass {

Object o;

public MyClass(Object o) {

this.o=o;

}

public Object get() {

return o;

}

}

class CallingClass {

public static void main(String[] args) {

MyClass m=new MyClass("Test);

String s=(String)m.get(); // compiler inserts cast here based on your type parameter

}

}

That is why you can't do what you wanted - because "there is no spoon" ;)

Generics in Java are only a compile time feature.

Cheers,

Adrian

AdrianSosialuka at 2007-7-12 > top of java,Core,Core APIs...
# 3

You can create an array if you know Class class for generic type:

public class AClass<K extends SomeObject>{

SomeObject[] AnArray;

public void amethod(Class<K> cls) {

//AnArray=new K[10];

AnArray = (K[]) java.lang.reflect.Array.newInstance(cls, 10);

}

}

raindropa at 2007-7-12 > top of java,Core,Core APIs...
# 4

Hi,

Yeah - it will work, but you will get a warning anyway. However:

1) If you get it anyway, why not write:

T[] t=new Integer[10];

or another appropriate type whenever you need to use an array ?

2) Shouldn't it be:

[...]

public void amethod(Class<? extends K> cls)

?

Cheers,

Adrian

AdrianSosialuka at 2007-7-12 > top of java,Core,Core APIs...
# 5
Of course I meant:T[] t=(T[])new Integer[10];
AdrianSosialuka at 2007-7-12 > top of java,Core,Core APIs...
# 6

> Yeah - it will work, but you will get a warning

> anyway. However:

>

> 1) If you get it anyway, why not write:

> > T[] t=new Integer[10];

>

> or another appropriate type whenever you need to use

> an array ?

In this way you could obtain the Class<T> class from the known T element:public class MyClass<T> {

private T[] array;

public MyClass(T elem){

array = (T[]) java.lang.reflect.Array.newInstance(elem.getClass(), 10);

}

}

What about warning, I think that newInstance method from Array class should be defined like static <T> T[] newInstance(Class<T> componentType, int length)

instead of static Object newInstance(Class<?> componentType, int length)

In this case no warning occurs.

>

> 2) Shouldn't it be:

> > [...]

> public void amethod(Class<? extends K> cls)

>

> ?

I do not see any advantages of this. May be someone else could explain

which suggestion is better.

>

> Cheers,

>

> Adrian

raindropa at 2007-7-12 > top of java,Core,Core APIs...
# 7

> In this way you could obtain the Class<T>

> class from the known T element:

Yes. You still need either Class object or T[]

or object of type parameter T. Is there any benefit

of using this solution over my proposal ?

> What about warning, I think that newInstance

> method from Array class should be defined like

> static <T> T[] newInstance(Class<T> componentType, int length)

Yes - that would be nice, but newInstance calls newArray, which

is native (so no generic information available ...). I don't know whether

that would be possible to have it implemented in generic way or not,

but honestly - I don't want to go through the API and make PhD ;)

Perhaps someone smarter could say why Sun has done it the way it is ...

> I do not see any advantages of this. May be someone

> else could explain

> which suggestion is better.

I was doing some experiments with your code and ended up

with some incompatibilities .... Unfortunately I have deleted all

the code and can't remind myself what it was :) However, one

of the benefits would be this:

AClass<Number> a=new AClass<Number>();

a.amethod(Integer.class);

The question remains - how Number[] n=new Integer[10];

can benefit ? Hmmmm .....

Cheers,

Adrian

AdrianSosialuka at 2007-7-12 > top of java,Core,Core APIs...
# 8
Testing
Diptiranjana at 2007-7-12 > top of java,Core,Core APIs...
# 9

> I do not see any advantages of this. May be someone

> else could explain

> which suggestion is better.

>

> I was doing some experiments with your code and ended

> up

> with some incompatibilities .... Unfortunately I have

> deleted all

> the code and can't remind myself what it was :)

> However, one

> of the benefits would be this:

> > AClass<Number> a=new AClass<Number>();

> a.amethod(Integer.class);

>

I do not understand your example because the original qwestion was

about AClass class: public class AClass<K extends SomeObject>{ }

butNumber does not extend SomeObject

class.

> The question remains - how Number[] n=new

> Integer[10];

In this case, expression n[0] = new Double(10.2);

throws ArrayStoreException

> can benefit ? Hmmmm .....

>

> Cheers,

>

> Adrian

raindropa at 2007-7-12 > top of java,Core,Core APIs...