Search code examples
javalistgenericstoarray

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?


Solution

  • 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);