我试图用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方法?如果这条线不起作用,我还有哪些其他选项,以便我可以拥有一个可以某种方式保存通用可比类型的数组?
答案 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编译器会将所有通用参数替换为我们提供的约束。
class Generic<T> { }
在这种情况下,java编译器生成字节码,该字节码将所有T类型替换为Object类。class Generic<T extends Number> { }
在内部将T替换为Number类。您将Comparable接口用作约束,因此在内部将所有T替换为Comparable,这就是为什么您无法将对象类型转换为可比较对象的原因
为了解决这个问题,您可以使用(T[]) new Comparable[50];