1

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?

pknbgr111
  • 11
  • 2
  • You've also got a compile error in your constructor. Please be sure that the code you're posting for debugging help compiles, and is able to reproduce the issue you're trying to get help with! :) – nbrooks Jul 31 '17 at 03:12
  • 1
    Possible duplicate of [How to create a generic array in Java?](https://stackoverflow.com/questions/529085/how-to-create-a-generic-array-in-java) – nbrooks Jul 31 '17 at 03:13
  • [This answer](https://stackoverflow.com/a/4221845/803925) specifically should be a good example of how to handle this situation. You'll end up doing something like `clazz.cast(Array.newInstance(clazz.getComponentType(), size))` where `clazz` is of type `Class` and would be a parameter to your constructor. You would pass in `Integer[].class` when you invoke it. This would be much easier if you were using collections rather than an array though. – nbrooks Jul 31 '17 at 03:21

3 Answers3

1

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];
}
}
Leeqihe
  • 21
  • 3
1

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];
newacct
  • 110,405
  • 27
  • 152
  • 217
0

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

Vikas Sharma
  • 435
  • 6
  • 10