2016-03-06 3 views
3

Я хотел бы выделить массив объектов, который включает общий тип для строго внутреннего использования.Java Generics: Array Casting


Объект:

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

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

} 

Массив:

private Node<E>[] elements; 

Бросок:

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

Почему я получаю ClassCastException?

+2

Поскольку объект [] не является узлом []. –

ответ

0

Причина, по которой актер не работает, заключается в том, что стирается стирание Node<E> до E внутри Node, но он не применяется к массивам Node<E>.

Тип стирание позволит вам бросить Node<E> к Node<Object>, потому что все Node<E> s являются Node<Object> под капотом. Аналогично, это позволит вам наложить Node<E>[] на Node<Object>[] и обратно, потому что массивы имеют один и тот же базовый тип - то есть Node<Object>.

Однако стирание типа не играет, когда вы имеете дело с массивами. Массив объектов остается массивом объектов, а Java имеет достаточно метаданных, чтобы знать его.

У вас есть несколько путей решения этой проблемы:

  • Переход от Node<E>[] к ArrayList<Node<E>> - массив список имеет схожие размеры и время доступа, и является общим
  • Используйте раствор из this Q&A - типа безопасного решения требует прохождения Class<E>.
1

Принятое решение отсюда следует сделать трюк:

casting Object array to Integer array error

Вы не можете разыгрывать Object [] к Node [] непосредственно, но вы можете использовать Arrays.copyOf() для создайте копию нужного типа. Единственный недостаток - это сделать копию, но это Java: если вы хотите, чтобы это не было медленным, вы бы не сделали этого самому себе;)

+0

фактически Arrays.copyOf использует Sytsem.arraycopy, который использует собственный код. Также java близок к C с точки зрения производительности: https://benchmarksgame.alioth.debian.org/u64q/java.html – Cyril

+0

Да, копия будет дешевой, потому что arraycopy не страшна (хотя у нее будут проверки границ, которые являются teensy накладными расходами). С другой стороны, единственная причина, по которой мы это сделали, - это недостаток в системе типов Java. –