创建新的通用引用

时间:2011-03-10 20:16:37

标签: java generics

我想使用一个数组实现两个堆栈。我还希望堆栈实现是通用的。这就是我所做的:

public class TwoStack<T>
{
    private T array[];

    public TwoStack(int size)
    {
        array = new T[size];
    }

    //additional push/pop implementation
}

但是编译器会在构造函数内部的行中抛出异常,说“无法创建泛型数组。

我知道由于类型擦除,我无法创建T类型的新对象。但为什么我不能创建对类型为T的对象的引用?

6 个答案:

答案 0 :(得分:3)

Java数组实际上在运行时知道它的组件类型。如您所知,泛型类(如TwoStack<T>)在运行时对其泛型参数一无所知。这就是为什么会发生冲突的原因。 T[]表示在运行时知道其组件类型T(或T的子类)的类。因此,您需要在运行时知道T来创建它。这不是你想要的。

有些人提到使用ArrayList<T>等,而不是数组。这是为什么?因为ArrayList<T>TwoStack<T>一样,在运行时不知道或不关心T,所以它是一个完美的匹配。

仍然可以使用数组吗?当然。 (ArrayList是使用数组实现的,所以任何可以用ArrayList完成的事情都可以用数组来完成。)但是正如我们之前建立的那样,T[]不是你想要的。

我们想要一些在运行时不关心T的东西。这是Object[]。所以我们必须在运行时创建Object[]。遗憾的是,Java中没有Object[]<T>,因此您将失去泛型的编译时优势。很多人为数组创建了通用的包装类,类似于Array<T>;您也可以轻松地创建一个,作为练习,但它不存在于Java库中。

如果要使用数组,有两个选项:

  1. 只需使用Object[],然后根据需要投射到您想要的元素,就像在泛型之前使用集合一样。你失去了仿制药的所有细节,但是你完全诚实地在板上工作。

  2. 谎言,欺骗并将Object[]投射到T[](即(T[])new Object[size])。现在,这表面看起来就像一个非法演员。 (如果您,例如创建Object[]并将其投放到String[],则会立即获得ClassCastException,因为Object[]不是String[]的子类,虽然它是另一种方式。)但请记住,只要你在泛型类中,T被删除到最低界限,即Object,所以Object[]Object[]演员阵容没问题。危险将推迟到以后的时间:如果您将此数组作为类型T[]返回,或者允许外部源获取对此数组的引用,并且您向它们承诺它是T[],并且那些人期望它是T[]的实际类型(例如String[]),编译器会插入一个演员,你将得到一个ClassCastException。但是,如果你注意不要将这个数组暴露给外面的世界,那么没有人会知道T[]这个谎言,你可以在它上面使用类型安全的操作而不会转换为T

答案 1 :(得分:1)

答案 2 :(得分:1)

这是因为在运行时,没有关于您在编译时使用的泛型类型的信息。因此,运行时无法知道您是想要Object[]还是String[]。您只需创建Object[]并稍后将其投放到T[]

答案 3 :(得分:0)

Java不允许构造没有反射或弱转换的通用数组。

答案 4 :(得分:0)

使用ArrayList而不是[]数组。它只是一点点慢,它可以用于此目的,而Java禁止你想要做的事情。

答案 5 :(得分:0)

Array是穷人的仿制品。

如果只允许Object[],那么Java就可以了。如果你只限于Object[],你就可以得到很好的结果。但就像非通用的List一样,使用它有点痛苦。程序员需要一些其他方法来提醒自己数组存储的对象类型。

因此,Java允许您指定数组中元素的类型,如Number[],类似于generified List<Number>。现在javac可以确保你没有插入错误类型的元素;而且你不必向下转换从数组中检索的元素;并且有一个简单的协方差(例如,Interger[]Number[]的子类型)

因此,在引入真正的泛型之前,数组在API中优于List。最好返回Number[]而不是原始List;后者很难用于来电者。

现在, 真正的仿制药,这些文学的好处不再是相关的。几乎在实施的任何地方,您需要X[],您可以使用ArrayList<X>代替;在AP的任何地方,您需要X[],您可以使用List<X>代替。

当您确实需要使用数组时,例如编程ArrayList<T>本身或其他一些基本数据结构时,可以仅使用Object[]。通用数组对你来说不会有太多帮助,同时它本身也很混乱。