Reputation: 800
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
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
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