Reputation: 11
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
Reputation: 735
When we apply constraint in generic class java compiler replaces all generic argument to constraint we have provided.
class Generic<T> { }
in this case java compiler generates bytecode which replaces all T types to Object class.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
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
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