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?
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.
The toArray() method of ArrayList is used to return an array containing all the elements in ArrayList in the correct order.
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[] .
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
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With