如何使用泛型初始化数组?

时间:2013-10-13 16:02:32

标签: java arrays generics

我正在用Java实现一个接口:

public interface Stack <E>{
    public int size();
    public boolean isEmpty();

实现它的类:

public class StackArray<E> implements Stack<E>{
    private Object list[];
    private int top=-1;
    public StackArray(int n){
        list=new Object[n];
    }

这很有效,所以当我打电话时,我这样做:

public static void main(String[] args) {
        // TODO code application logic here
        StackArray<Students> st=new StackArray<>(4);

所以我如何实现它,但使用泛型,我试过这个:

public class StackArray<E> implements Stack<E>{
    private E st[];
    private int top=-1;
    public StackArray(int n){
        st=(E[]) Array.newInstance(null, n);
    }

但是我得到了一个nullPointerException,有没有办法消除这个?

2 个答案:

答案 0 :(得分:1)

由于type erasure,您在某些时候需要在创建对象数组时传递实际的类(或通过getClass()从中获取类的实际对象)。您无法将null作为第一个参数传递给Array.newInstance;你需要一个真正的课程。一种方法是:

public class StackArray<E> implements Stack<E>{
    private E st[];
    private int top=-1;
    public StackArray(Class<E> type, int n) {
        st=(E[]) Array.newInstance(type, n);
    }
}

您需要使用实际类型来调用它,而不是null。例如:

StackArray<Integer> stack = new StackArray<>(Integer.class, 20);

您也可以将构造函数声明为

    public StackArray(Class<? extends E> type, int n) {

但我没有看到太多的优势(以及一些风险)。

然而,一般来说,将数组与泛型混合是一个坏主意。我建议你重新考虑你的设计。

答案 1 :(得分:0)

您无法在Java中创建通用数组。

由于这一行,你得到NullPointerException

Array.newInstance(null, n);

从该方法的Javadoc开始:

Parameters:
    componentType - the Class object representing the component type of the new array
    length - the length of the new array
Returns:
    the new array
Throws:
    NullPointerException - if the specified componentType parameter is null
    IllegalArgumentException - if componentType is Void.TYPE
    NegativeArraySizeException - if the specified length is negative

您可以看到,如果NullPointerExceptioncomponentType,它会声明会抛出null

一个 hack 是创建Object[]然后投射它:

public StackArray(int n){
    st=(E[]) new Object[n];
}

我说黑客,因为这太可怕了,应该避免。您可以做的最好的事情是使用java集合API并将您的类更改为

public class StackArray<E> implements Stack<E>{
    private List<E> st;
    private int top=-1;

    public StackArray(int n){
        st = new ArrayList<E>(n);
    }

    //...
}