Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 508
watchzerg Avatar asked Nov 13 '12 03:11

watchzerg


People also ask

What does public &lt T&gt T [] toArray T [] a mean?

public <T> T[] toArray(T[] a) The toArray() method is used to get an array which contains all the elements in ArrayList object in proper sequence (from first to last element); the runtime type of the returned array is that of the specified array. If the list fits in the specified array, it is returned therein.

What is the use of toArray () in Java?

The toArray() method of ArrayList is used to return an array containing all the elements in ArrayList in the correct order.

Why does toArray return object?

Because arrays have been in Java since the beginning, while generics were only introduced in Java 5. And the List. toArray() method was introduced in Java 1.2, before generics existed, and so it was specified to return Object[] .


2 Answers

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

like image 109
Alex Avatar answered Sep 30 '22 13:09

Alex


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);
like image 35
watchzerg Avatar answered Sep 30 '22 11:09

watchzerg