pknbgr111
pknbgr111

Reputation: 11

Casting object to comparable runtime error

I'm attempting to write code for a BinarySearchTree in Java. I keep getting a runtime error when I try to test it by instantiating an Integer BST. Here's the relevant code:

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

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

Now, I have this line in main:

BinarySearchTree<Integer> test = new BinarySearchTree<Integer>();

When I run the code I get this error linked to the first line of the constructor:

[Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable;

I'm not very familiar with generics, but I'm guessing this is because Object doesn't have a defined compareTo method? If this line won't work, what other options do I have so that I can have an array that can somehow hold the generic Comparable types?

Upvotes: 1

Views: 927

Answers (3)

Vikas Sharma
Vikas Sharma

Reputation: 735

When we apply constraint in generic class java compiler replaces all generic argument to constraint we have provided.

  1. class Generic<T> { } in this case java compiler generates bytecode which replaces all T types to Object class.
  2. class Generic<T extends Number> { } here internally it replaces T with Number class.

you are using Comparable interface as a constraint so internally it replaces all T's with Comparable that's why you can't cast object type to comparable to solve this you can use (T[]) new Comparable[50];

Upvotes: 0

Leeqihe
Leeqihe

Reputation: 21

You get this Exception because the array's runtime class is [Object (as your code "new Object[10]"). As Object is the super class of all others, you cannot cast an object array to any other type array.

1.Cannot cast A-Type-Array to B-Type-Array, except A is B' subclass.
2.Event cast Sub-Type-Array to Super-Type-Array, the array still store Sub-Type element only, as the runtime type is still [Sub-Type.

You can try with below code:

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
}

As your situation, I think you should coding like below:

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];
}
}

Upvotes: 1

newacct
newacct

Reputation: 122429

The erasure of E[] is Comparable[] (because the upper bound of E is Comparable<E>), so at runtime, it will cast to Comparable[], which fails because the actual runtime type of the object is Object[]. You can solve this problem by creating a Comparable[] instead:

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

Upvotes: 1

Related Questions