由于Java泛型的实现,你不能有这样的代码:

public class GenSet<E> {
    private E a[];

    public GenSet() {
        a = new E[INITIAL_ARRAY_LENGTH]; // error: generic array creation
    }
}

如何在保持类型安全的同时实现这一点?

我在Java论坛上看到一个解决方案是这样的:

import java.lang.reflect.Array;

class Stack<T> {
    public Stack(Class<T> clazz, int capacity) {
        array = (T[])Array.newInstance(clazz, capacity);
    }

    private final T[] array;
}

但我真的不明白这是怎么回事。


当前回答

再看看这段代码:

public static <T> T[] toArray(final List<T> obj) {
    if (obj == null || obj.isEmpty()) {
        return null;
    }
    final T t = obj.get(0);
    final T[] res = (T[]) Array.newInstance(t.getClass(), obj.size());
    for (int i = 0; i < obj.size(); i++) {
        res[i] = obj.get(i);
    }
    return res;
}

它将任何类型的对象的列表转换为相同类型的数组。

其他回答

我找到了一个解决这个问题的方法。

下面这行代码抛出泛型数组创建错误

List<Person>[] personLists=new ArrayList<Person>()[10];

但是,如果我将List<Person>封装在一个单独的类中,它就可以工作。

import java.util.ArrayList;
import java.util.List;


public class PersonList {

    List<Person> people;

    public PersonList()
    {
        people=new ArrayList<Person>();
    }
}

您可以通过getter在PersonList类中公开人员。下面的行将给出一个数组,每个元素中都有List<Person>。也就是说数组List<Person>。

PersonList[] personLists=new PersonList[10];

我需要这样的东西在一些代码中,我正在工作,这就是我所做的让它工作。到目前为止还没有问题。

这在Effective Java第二版第5章(泛型)第25项中有介绍…更喜欢列表而不是数组

你的代码将会工作,尽管它会生成一个未检查的警告(你可以用下面的注释来抑制它):

@SuppressWarnings({"unchecked"})

然而,使用List而不是Array可能会更好。

在OpenJDK项目网站上有一个关于这个bug/特性的有趣讨论。

在java中不允许创建通用数组,但是你可以这样做

class Stack<T> {
private final T[] array;
public Stack(int capacity) {
    array = (T[]) new Object[capacity];
 }
}

传递一个值列表…

public <T> T[] array(T... values) {
    return values;
}

您可以创建一个Object数组,并在所有位置将其强制转换为E。是的,这不是很干净的方法,但至少应该是可行的。