将对象转换为可比运行时错误

时间:2017-07-31 02:58:16

标签: java generics comparable

我试图用Java编写BinarySearchTree的代码。当我尝试通过实例化整数BST来测试它时,我不断收到运行时错误。这是相关代码:

public class BinarySearchTree<E extends Comparable<E>> {
    private E[] nodes;

    @SuppressWarnings("unchecked")
    public BinarySearchTree() {
            nodes = (E[])new Object[10];
    }
}

现在,我在main中有这一行:

BinarySearchTree<Integer> test = new BinarySearchTree<Integer>();

当我运行代码时,我将此错误链接到构造函数的第一行:

[Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable;

我不熟悉泛型,但我猜这是因为Object没有定义的compareTo方法?如果这条线不起作用,我还有哪些其他选项,以便我可以拥有一个可以某种方式保存通用可比类型的数组?

3 个答案:

答案 0 :(得分:1)

你得到这个异常,因为数组的运行时类是[Object(作为你的代码“new Object [10]”)。由于Object是所有其他类的超类,因此无法将对象数组转换为任何其他类型数组。

1.Cannot将A-Type-Array转换为B-Type-Array,除了A是B'子类 2.Event将Sub-Type-Array转换为Super-Type-Array,该数组仍然只存储Sub-Type元素,因为运行时类型仍为[Sub-Type。

您可以尝试使用以下代码:

public static void main(String[] args) {
    Object[] arr = new Object[10];
    Integer[] irr = (Integer[]) arr;// error: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;
}

public static void main(String[] args) {
    Integer[] irr = new Integer[10];
    Object[] arr = irr; 
    arr[0] = new Object(); // java.lang.ArrayStoreException: java.lang.Object
}

根据您的情况,我认为您应该编码如下:

class BinarySearchTree<E extends Comparable<E>> {
private Comparable<E>[] nodes;

@SuppressWarnings("unchecked")
public BinarySearchTree() {
        nodes = new Comparable[10];
}

public void add(E e, int index){
    nodes[index] = e;
}

@SuppressWarnings("unchecked")
public E get(int index){
    return (E)nodes[index];
}
}

答案 1 :(得分:1)

E[]的删除是Comparable[](因为E的上限是Comparable<E>),所以在运行时,它会转换为Comparable[],失败的原因是对象的实际运行时类型为Object[]。您可以通过创建Comparable[]来解决此问题:

nodes = (E[])new Comparable[10];

答案 2 :(得分:0)

当我们在通用类中应用约束时,java编译器会将所有通用参数替换为我们提供的约束。

  1. class Generic<T> { }在这种情况下,java编译器生成字节码,该字节码将所有T类型替换为Object类。
  2. class Generic<T extends Number> { }在内部将T替换为Number类。

您将Comparable接口用作约束,因此在内部将所有T替换为Comparable,这就是为什么您无法将对象类型转换为可比较对象的原因 为了解决这个问题,您可以使用(T[]) new Comparable[50];