3

如果我有一个Collection定义为Collection collection = new ArrayList()包含String实例,我怎样才能将它转换为一个String[]collection.toArray()返回一个Object[]. 或者,如何实例化ArrayList<String>使用反射?

请注意,我不能硬编码String,这样做的方法只知道Class它可以使用的方法。

例子:

Object test(Class classToCastTo, Object[] values) {
    Collection collection = new ArrayList();
    for (Object value : values) {
        collection.add(classToCastTo.cast(value));
    }
    return collection.toArray();
}

如果我用 调用它test(String.class, ...),那么它将返回一个Object[]. 我怎样才能让它返回一个String[]

4

7 回答 7

4

使用theCollection.toArray((T[])java.lang.reflect.Array.newInstance(theClass, theCollection.size())),其中T是元素类型。只要T是未参数化的类型,强制转换是安全的。

于 2012-07-15T16:16:27.540 回答
1

如果你有这个类,你可以写一个这样的方法:

public static <T> T[] arrayBuilder(Class<T> classToCastTo, Collection c) {
  return (T[]) c.toArray((T[]) Array.newInstance(classToCastTo, 0));
}
于 2012-07-15T16:29:42.877 回答
0

这似乎可以满足您的需要:

public static void main(String[] args) {
    Object[] originalArray = {"abc", "def"};
    Class clazz = String.class;

    Object[] newArray = test(clazz, originalArray);
    System.out.println(newArray.getClass()); //class [Ljava.lang.String;
    System.out.println(Arrays.toString(newArray)); //[abc, def]
}

static Object[] test(Class classToCastTo, Object[] values) {
    Object[] o = (Object[]) Array.newInstance(classToCastTo, values.length);
    System.arraycopy(values, 0, o, 0, values.length);
    return o;
}

java.lang.ArrayStoreException如果原始数组包含不是 a 的内容,您将得到a String

于 2012-07-15T16:06:41.277 回答
0

根据 Ben 的回答,以下代码片段有效(编译时没有警告并运行):

private static Object test(Class<?> classToCastTo, Object[] values) {
    Collection<Object> collection = new ArrayList<Object>();
    for (Object value : values) {
        collection.add(classToCastTo.cast(value));
    }

    return collection.toArray(
        (Object[]) java.lang.reflect.Array.newInstance(
            classToCastTo, collection.size())
    );
}

现在您可以通过以下方式调用该方法

String[] result = (String[]) test(String.class, someValues);

诀窍是将通过反射创建的数组强制转换为Object[]满足静态类型检查并匹配toArray.

也就是说,我不明白为什么不能使用泛型参数调用该方法。如果你在某处没有泛型类型,那么这个方法的结果无论如何都是无用的。

于 2012-07-15T16:30:58.560 回答
0

遍历 Collection 并将其存储在 String 数组中。

从我的代码中尝试这个例子:

Collection c = new ArrayList();
c.add("Vivek");
c.add("Vishal");
String[] arr = new String[ c.size()];
int j = 0;
for (Object s : c){

arr[j] = (String)s;
j++;
}
于 2012-07-15T16:09:04.473 回答
0

以下方法是您要找的

public <T> T[] test(Class<T> classToCastTo, Object[] values) {
    Collection<T> collection = new ArrayList<T>();
    for (Object value : values) {
        collection.add(classToCastTo.cast(value));
     }
    return collection.toArray((T[])Array.newInstance(classToCastTo, collection.size()));
}
于 2012-07-15T16:24:19.507 回答
0

如果你知道你的集合只包含字符串,这个方法

public static <T>  T[] toArray(Collection collection, Class<T> clazz) {
    T[] array = (T[]) Array.newInstance(clazz, collection.size());
    return ((Collection<T>) collection).toArray(array);
}

称为

String[] result = toArray(collection, String.class);

会做你需要的,虽然它会给出一些关于未经检查的演员的警告。

如果你知道你的集合只能包含字符串,你应该能够将它声明为 aCollection<String>并避免这种混乱。

于 2012-07-15T16:49:12.597 回答