sir psycho sexy
sir psycho sexy

Reputation: 800

Cast Exception when using a Comparable array on Java

I'm trying to add methods to change the priority of an element on a process binary heap that is a non generic Class, but it is a subclass of a generic one. The problem appears when I try to assign a Comparable array element which is casted to a generic type T to a Process variable I get a java.lang.ClassCastException: [Ljava.lang.Comparable; cannot be cast to [Ltp07.ejercicio3.Proceso;. Consider that I was asked to declare the array as Comparable and cast it to T to bypass java not allowing to declare a generic array.

I have:

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

}

Then there is this simple user defined class Process that is declared as public class Process implements Comparable<Process>

And:

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

}

So my question is how can avoid this Exception without changing the MaxHeap Class implementation if possible (this is for academic purpose and I am expected to do this in this way)? and also, trying to go beyond to what my teachers asked me, is a good practice to do what I done in the second sentence of the MaxHeap class, casting to Comparable to be able to have a generic array? what about if I try to implement a data structure generic class were the objects aren't expected even to be comparable, I will have to cast it to Object, that sounds even worse, or there is another way to solve this kind of issue?

EDIT:

the error appears at runtime when decreasePriority()` is called and it reaches the marked line

Process class is declared as: public class Process implements Comparable<Process> and the compiler, in case it is related with the solution, doesn't allow me to declare it as public class Process implements Comparable complaining that Comparable is a raw type and references to generic type Comparable should be parametrized.

Upvotes: 0

Views: 231

Answers (2)

newacct
newacct

Reputation: 122429

The array's actual runtime type is Comparable[], which is not assignable to T[] (unless T is exactly Comparable), so the cast is not theoretically correct. This "lie" doesn't cause any problems as long as data is only used within the inside of MaxHeap, where T is erased to Comparable.

However, if you expose data as type T[] to an outside scope where T is expected to be a specific type, then that will cause cast exceptions. In this case, the protected variable data is exposed to the subclass ProcessQueue, which specifies a specific type (Process) for T. So it expects data to be a Process[], but it isn't. That causes the exception.

Upvotes: 1

Sanjay Manohar
Sanjay Manohar

Reputation: 7026

Your error is because one item in data is not a Process.

What this means is that the items in the Comparable array are not Processes. You haven't shown us the class declaration, nor where you create the processes. This seems to be important.

You need your processes to be declared

class Process extends ... implements Comparable {
}

and you need to initialise the array with the new processes somewhere, e.g.

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

Upvotes: 0

Related Questions