list.toArray(T[] a)
,如果T
是“运行时类型”怎么办?
“List
”接口,方法:T[] toArray(T[] a)
好吧,这是一个很老的问题,通常我们会这样使用它:
String[] array = list.toArray(new String[0]);
String[] array = list.toArray(new String[list.size()]);
我的问题是,我不知道编码时类型“T”是什么,类型“T”只能在运行时决定,这里是示例:
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
现在我需要将列表转换为元素类型为clazz的数组,我该怎么办?
可能你想知道为什么我有这种需要:
我正在对Morphia进行一些修改(这是一个java-mongoDB框架)。我需要从mongoDB获取数据并将其设置为POJO的右侧字段。在某些情况下,字段类型是数组,所获取的数据是BasicDBList实体(它扩展了ArrayList),因此BasicDBList实体必须转换为类型与POJO字段兼容的数组。
我查看了ArrayList的源代码,然后用一些丑陋的代码实现了我的目标:
List list=...;
Class<?> clazz=...;
Object targetArray=Array.newInstance(clazz, list.size());
list.toArray((Object[])targetArray);
有没有更好的方法呢?
答案 0 :(得分:5)
如果您的类型仅在运行时已知,则此处没有解决方案。
Java Generics是一个编译时检查,在运行时实际上并不存在,它被称为类型擦除http://docs.oracle.com/javase/tutorial/java/generics/erasure.html
这意味着运行时环境不进行此类检查(例如,您可以将Integers放入一般列为String的List中,并使用Object o = list.get(0)运行就好了)
泛型的真正意义在于提供编译时检查以防止编码错误
答案 1 :(得分:1)
在@ arne.b的评论帮助中,我认为没有更好的方法可以做到这一点:
List list=...;
Class<?> clazz=...;
Object[] targetArray=(Object[])Array.newInstance(clazz, list.size());
Object[] myArray=list.toArray(targetArray);
然后我可以将其设置为字段而不会出错:
Field field=...; //ComponentType of this field can be sure is "clazz"
field.set(entity,myArray);
或者我可以这样做手动将其转换为它的结构类型:
Class<?> arrayClazz=Class.forName("[L"+clazz.getName()+";");
arrayClazz.cast(myArray);