3

I would like to cast an array of object which involves a generic type for strictly internal usage.


The object:

private class Node<T>
{
    T element;
    int prior;

    public Node(T element, int prior)
    {
        this.element=element;
        this.prior=prior;
    }

}

The array:

private Node<E>[] elements;

The cast:

public PriorityQueue()
{   
  elements = (Node<E>[])new Object[capacity]; // ClassCastException
}

Why do i get ClassCastException?

freestar
  • 357
  • 1
  • 12

2 Answers2

1

The accepted solution from here ought to do the trick:

casting Object array to Integer array error

You can't cast an Object[] to a Node[] directly, but you can use Arrays.copyOf() to create a copy of the right type. Only downside is this involves doing a copy, but it's Java: if you wanted it to not be slow you wouldn't have done this to yourself ;)

Community
  • 1
  • 1
Chris Kitching
  • 2,323
  • 18
  • 32
  • actually Arrays.copyOf uses Sytsem.arraycopy which uses native code. Also java is close to C in terms of performance: https://benchmarksgame.alioth.debian.org/u64q/java.html – Cyril Mar 06 '16 at 12:18
  • Yes, the copy will be cheap because arraycopy isn't terrible (though it will have bounds checks which are a teensy overhead). On the other hand, the only reason we _need_ this copy is because of a flaw in Java's type system. – Chris Kitching Mar 06 '16 at 12:19
0

The reason the cast does not work is that type erasure of Node<E> applies to E inside Node, but it does not apply to arrays of Node<E>.

Type erasure would let you cast Node<E> to Node<Object> because all Node<E>s are Node<Object> under the hood. Similarly, it would let you cast Node<E>[] to Node<Object>[] and back, because the arrays share the same underlying type - that is, Node<Object>.

However, type erasure is not in play when you deal with arrays. An array of objects remains an array of objects, and Java has enough metadata to know it.

You have several ways of solving this problem:

  • Switch from Node<E>[] to ArrayList<Node<E>> - array list has similar footprint and access times, and is generic
  • Use a solution from this Q&A - type-safe solution requires passing Class<E>.
Community
  • 1
  • 1
Sergey Kalinichenko
  • 675,664
  • 71
  • 998
  • 1,399