Java 将对象强制转换为可比较的运行时错误

Java 将对象强制转换为可比较的运行时错误,java,generics,comparable,Java,Generics,Comparable,我正在尝试用Java为BinarySearchTree编写代码。当我试图通过实例化一个整数BST对其进行测试时,我不断收到一个运行时错误。以下是相关代码: public class BinarySearchTree<E extends Comparable<E>> { private E[] nodes; @SuppressWarnings("unchecked") public BinarySearchTree() {

我正在尝试用Java为BinarySearchTree编写代码。当我试图通过实例化一个整数BST对其进行测试时,我不断收到一个运行时错误。以下是相关代码:

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

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

我不太熟悉泛型,但我猜这是因为对象没有定义compareTo方法?如果这一行行不通,我还有什么其他选项可以让数组以某种方式保存泛型可比类型?

由于数组的运行时类是[Object(作为代码“new Object[10]”),因此会出现此异常。由于对象是所有其他类型的超类,因此不能将对象数组强制转换为任何其他类型的数组。

1.无法将A-Type-Array强制转换为B-Type-Array,除非A是B'子类。
2.事件将子类型数组强制转换为超级类型数组,该数组仍然只存储子类型元素,因为运行时类型仍然是[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];
}
}
类二进制搜索树{
私有节点;
@抑制警告(“未选中”)
公共二进制搜索树(){
节点=新的可比[10];
}
公共无效添加(E、E、int索引){
节点[索引]=e;
}
@抑制警告(“未选中”)
公共E-get(int索引){
返回(E)节点[索引];
}
}

E[]
的擦除是
Comparable[]
(因为
E
的上限是
Comparable
),所以在运行时,它将转换为
Comparable[]
,这会失败,因为对象的实际运行时类型是
object[]
。您可以通过创建
Comparable[]来解决这个问题
相反:

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

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

  • class Generic{}
    在本例中,java编译器生成字节码,将所有T类型替换为对象类
  • 类泛型{}
    在内部,它用数字类替换T
  • 您使用Comparable接口作为约束,因此在内部它将所有T替换为Comparable,这就是为什么您不能将对象类型强制转换为Comparable
    要解决这个问题,您可以使用
    (T[])new Comparable[50];

    您的构造函数中还有一个编译错误。请确保您发布的用于调试帮助的代码已编译,并且能够重现您试图获得帮助的问题!:)的可能重复应该是如何处理这种情况的一个很好的示例。您最终将执行类似于
    clazz.c的操作ast(Array.newInstance(clazz.getComponentType(),size))
    其中
    clazz
    属于
    Class
    类型,将是构造函数的一个参数。调用它时,可以传入
    Integer[].Class
    。不过,如果使用的是集合而不是数组,这会容易得多。
    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];
    }
    }
    
    nodes = (E[])new Comparable[10];