0

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.

2
  • Copy pasted your code and after changing implements PriorityQueue<T> to extends PriorityQueue<T> works fine (with what you posted here) Commented Nov 20, 2015 at 22:50
  • I can't do that with the complete source code, PriorityQueue is an interface, and I don't think that the problem is too much related with that interface. Commented Nov 20, 2015 at 22:59

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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(); 

1 Comment

I just added the Process class declaration to the original post, the Process class is a pretty basic class with just a few getters and setters, the only remarkable thing about it is that it extends Comparable thus it have a compareTo() method, the instanciation of it is pretty much trivial. In respect to the initialization of the array, the instantion of the array elements is correctly made through an addElement() in the PriorityQueue Class which mainly resolves it through the superclass MaxHeap

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.