Question

list.toArray(T[] a), what if the T is a "runtime type"?

"List" interface in Java, the method: T[] toArray(T[] a)
OK, it's a quite old question, usually we use it like that:

String[] array = list.toArray(new String[0]);
String[] array = list.toArray(new String[list.size()]);

My problem is, I don't know what the type "T" is when I was coding, the type "T" can only be decide in runtime,here is example:

List list=...;  // no generic type declared on this List
Class<?> clazz=...; //yeah, this is the real type of the element of the list, I can sure about that

Now I need to convert the list into an array which element type is clazz, what should I do?

May be you are wondering why do I have this kind of need:
I am making a little modification onto Morphia(It's a java-mongoDB framework). I need to aquire data from mongoDB and set it into right field of a POJO. In certain circumstance, the field type is array, the data aquired is a BasicDBList entity(which extends ArrayList),so the BasicDBList entity had to be convert into an array which type is compatible with the POJO filed.

I looked into source code of ArrayList, then achieved my goals with some ugly code:

List list=...;
Class<?> clazz=...;
Object targetArray=Array.newInstance(clazz, list.size());
list.toArray((Object[])targetArray);

Is there any better way to do this please?

Was it helpful?

Solution 2

With @arne.b 's help in the comments, I think there is no better way to do this:

List list=...;
Class<?> clazz=...;
Object[] targetArray=(Object[])Array.newInstance(clazz, list.size());
Object[] myArray=list.toArray(targetArray);

Then I can set it to field without error:

Field field=...;    //ComponentType of this field can be sure is "clazz"
field.set(entity,myArray);

Or I can do this to convert it to it's actrual type manually:

Class<?> arrayClazz=Class.forName("[L"+clazz.getName()+";");
arrayClazz.cast(myArray);

OTHER TIPS

If your type is only known at runtime there is no solution here.

Java Generics are a compile time check and do not actually exist at runtime, it's called type erasure http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

Meaning the runtime environment makes no such checks (for example, you can put Integers into a List generically typed as String and using Object o = list.get(0) would run just fine)

The real point of generics is to provide compile time checks to prevent coding errors

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top