在Java

时间:2015-11-20 22:25:11

标签: java arrays generics casting

我正在尝试添加方法来更改非泛型类的进程二进制堆上的元素的优先级,但它是泛型类的子类。当我尝试将Comparable数组元素分配给通用类型TProcess变量时,会出现问题,我得到java.lang.ClassCastException: [Ljava.lang.Comparable; cannot be cast to [Ltp07.ejercicio3.Proceso;。考虑我被要求将数组声明为Comparable并将其强制转换为T以绕过java,不允许声明泛型数组。

我有:

public class MaxHeap<T extends Comparable<T>> implements PriorityQueue<T> {

    @SuppressWarnings ("unchecked")
    protected T[] data = (T[]) new Comparable[100]; 
    protected int elementsAmount = 0;

//some class methods

}

然后有一个简单的用户定义类Process,声明为public class Process implements Comparable<Process>

public class ProcessQueue extends MaxHeap<Process> {

public void decreasePriority (int position, int decrement) {
    Process temp;
    if (position > 0 && position <= elementsAmount) {
        temp = data[position];      //this is the line that generates the cast Exception
        temp.setPriority(temp.getPID()- decrement);
        data[position] = temp;      //and I guess probably this line will generate another one if the execution reach this point
        percolateDown(pos);         
    }

//some other methods

}

所以我的问题是,如果可能的话,如何在不改变MaxHeap类实现的情况下避免这种异常(这是出于学术目的,我希望以这种方式做到这一点)?并且,尝试超越我的老师问我的,在MaxHeap类的第二句中完成我所做的事情是一个很好的做法,转换为Comparable能够拥有一个通用数组?如果我尝试实现一个数据结构泛型类,那么对象是不可预期的甚至是可比较的,我将不得不将其转换为Object,这听起来更糟,还是有另一种方法可以解决这类问题?

编辑:

当调用decreasePriority()`并且它到达标记的行

时,错误出现在运行时

进程类声明为:public class Process implements Comparable<Process>和编译器,如果它与解决方案相关,则不允许我将其声明为public class Process implements Comparable抱怨Comparable是原始类型和引用to generic type Comparable应该是参数化的。

2 个答案:

答案 0 :(得分:1)

数组的实际运行时类型为Comparable[],不能分配给T[](除非T正好是Comparable),所以投射不是理论上是正确的。这个&#34;谎言&#34;只要data仅在MaxHeap内部使用,T被删除为Comparable,就不会导致任何问题。

但是,如果将data作为类型T[]公开到预期T是特定类型的外部作用域,那么这将导致强制转换异常。在这种情况下,protected变量data会向子类ProcessQueue公开,后者为Process指定特定类型(T)。因此,它希望dataProcess[],但它不是。{0}。这导致了例外。

答案 1 :(得分:0)

您的错误是因为data中的一个项目不是Process

这意味着Comparable数组中的项目不是Processes。您还没有向我们展示类声明,也没有向您展示创建流程的位置。这似乎很重要。

您需要声明您的流程

class Process extends ... implements Comparable {
}

并且您需要在某处使用新进程初始化数组,例如

for(int i=0;i<100;i++) data[i]=new Process();