Java 在数组(T[]a)中,如果;";是一个;运行时类型";?

Java 在数组(T[]a)中,如果;";是一个;运行时类型";?,java,list,generics,toarray,Java,List,Generics,Toarray,list.toArray(T[]a),如果T是一种“运行时类型”,该怎么办 Java中的“List”接口,方法:T[]toArray(T[]a) 好的,这是一个很老的问题,通常我们这样使用: String[] array = list.toArray(new String[0]); String[] array = list.toArray(new String[list.size()]); 我的问题是,我编码时不知道“t”是什么类型,只能在运行时确定“t”类型,下面是示例: List lis

list.toArray(T[]a)
,如果
T
是一种“运行时类型”,该怎么办

Java中的“
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=//是的,这是列表中真正的元素类型,我可以肯定
现在我需要将列表转换为一个数组,该数组的元素类型是clazz,我应该怎么做

也许你想知道我为什么有这种需要:
我正在对Morphia进行一些修改(它是一个JavaMongoDB框架)。我需要从mongoDB获取数据,并将其设置到POJO的右字段中。在某些情况下,字段类型为array,获取的数据是BasicDBList实体(扩展了ArrayList),因此必须将BasicDBList实体转换为与POJO字段兼容的数组类型

我研究了ArrayList的源代码,然后用一些难看的代码实现了我的目标:

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

请问有没有更好的办法

如果您的类型仅在运行时已知,则此处没有解决方案

Java泛型是一种编译时检查,在运行时实际上不存在,称为类型擦除

这意味着运行时环境不进行此类检查(例如,您可以将整数放入一个一般类型为String的列表中,并使用Object o=List.get(0)即可正常运行)


泛型的真正意义在于提供编译时检查以防止编码错误

在@arne.b的帮助下,我认为没有更好的方法可以做到这一点:

List list=...;
Class<?> clazz=...;
Object[] targetArray=(Object[])Array.newInstance(clazz, list.size());
Object[] myArray=list.toArray(targetArray);
或者我可以手动将其转换为实际类型:

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

您的解决方案是正确的,
Array.newInstance()
就是正确的选择。
list.toArray((Object[])targetArray;
为您提供了一个
对象
数组,对吗?那么为什么不使用不带参数的
toArray()
方法(并将返回值分配给
targetArray
)?@arne.b
list.toArray((Object[]))targetArray);
给我一个
对象数组
,但我可以这样做:
clazz.cast()
,因为里面是一个“clazz类型数组”。如果我使用
to array()
,我会得到一个
对象数组
,它不能被转换为任何其他数组类型。请尝试一下。对不起,我的错,我没有想到那种可能性(可能是因为
BasicDBList
扩展了
ArrayList
,所以我不知道如何从中获得除对象数组之外的任何东西)。但是如何从
对象中获得相应数组类的对象呢?(顺便说一句:如果没有比你自己的解决方案更好的方法,那么就可以为你自己的问题写一个答案。)@watchzerg:你应该声明
targetArray
Object[]targetArray=(Object[])Array.newInstance(clazz,list.size());
Class<?> arrayClazz=Class.forName("[L"+clazz.getName()+";");
arrayClazz.cast(myArray);