创建通用数组时的Java类转换异常

时间:2014-01-26 01:14:34

标签: java arrays generics

我正在尝试编写一个PriorityQueue,它必须通用化为Comparable。这是构造函数:

public class DavidiArrayPriorityQueue <E extends Comparable<E>> implements PriorityQueue<E> {

    private E data[];
    private int numElements;

    //creates an empty priority queue with 10 spaces by default
    public DavidiArrayPriorityQueue(){

        data= (E[]) new Object[20];
        numElements=0;
    }

当我用

初始化它时
DavidiArrayPriorityQueue<Integer> test=new DavidiArrayPriorityQueue<Integer>();

抛出[Ljava.lang.Object;无法转换为[Ljava.lang.Comparable;

1 个答案:

答案 0 :(得分:4)

数组的元素类型实际上是数组的一部分,在运行时已知。因此,当您编写new Object[]时,您正在创建一个元素类型为Object的数组,即使您的意图是数组的元素都将始终具有类型(例如)Comparable ,你仍然无法将其投射到Comparable[]

在您的情况下,您将其投射到E[]。由于擦除,演员阵容无法在运行时完全执行,因此将其降级为Comparable[]的演员阵容;所以,从技术上讲,你可以通过编写(E[]) new Comparable[]来欺骗编译器允许这样做。但这是一个坏主意,因为那时你有一个E[]类型的数组表达式,其元素类型实际上不是E。您已经规避了类型系统,这可能会在以后引起混淆错误。

最好让data属于Object[]类型(或者Comparable<?>[]),并对E执行必要的强制转换。这将导致编译器警告,因为编译器也无法检查这些强制转换,但至少可以验证您的代码是否正确并正确保留了类型系统(然后通过注释禁止警告)