[英]java generic casting in generic classes
我正在編寫一個通用max堆的簡單實現。 如果我寫
public class FastMaxHeap<T>{
T[] data;
int size;
static final int HEAP_SIZE = 10000;
@SuppressWarnings("unchecked")
public FastMaxHeap(){
data = (T[]) new Object[HEAP_SIZE];
size = 0;
}
}
它編譯。 現在要實際實現堆,即編寫maxHeapify(),我需要能夠比較兩個T。 先驗似乎可行的一種選擇是告訴編譯器T實現Comparable。 但是,如果我用<T實現Comparable>來替換<T>,編譯器會抱怨-我該怎么做?
另外,我可以定義一個類
public class HasValue{
int value;
public HasValue(int value){
this.value = value;
}
}
從理論上講,我應該能夠比較兩個HasValue對象,例如x.value> y.value。 但是如果我輸入
public class FastMaxHeap<T extends HasValue>{
T[] data;
int size;
static final int HEAP_SIZE = 10000;
@SuppressWarnings("unchecked")
public FastMaxHeap(){
data = (T[]) new Object[HEAP_SIZE];
size = 0;
}
}
我現在得到一個ClassCastException。 這里發生了什么? Java泛型傷害了我的大腦。
在第一種情況下, T extends Object
,該Object
在運行時被擦除為Object
。
在第二種情況下, T extends HasValue
擦除為HasValue
因此您需要擁有。
data = (T[]) new HasValue[HEAP_SIZE];
恕我直言,Java不允許new T[HEAP_SIZE]
來做您必須做的事情,這是不必要的。
您可以嘗試這一步(尚未編譯)
public class FastMaxHeap<T extends HasValue>{
HasValue[] data;
int size;
static final int HEAP_SIZE = 10000;
public FastMaxHeap(){
data = new HasValue[HEAP_SIZE];
size = 0;
}
}
最好有類型標記來創建這樣的數組
public class FastMaxHeap<T>{
T[] data;
int size;
static final int HEAP_SIZE = 10000;
@SuppressWarnings("unchecked")
public FastMaxHeap(Class<T> clazz){
data = (T[])Array.newInstance(clazz, HEAP_SIZE);
size = 0;
}
}
這樣,您將在運行時沒有ClassCastExceptions
而且: < T implements Comparable >
不正確,正確的是< T extends Comparable >
您的堆應接受Comparator <T>作為構造函數參數。 問題解決了。 客戶可以使用他想要的任何類型。 您還可以提供一個簡單的重載,它推斷已經實現Comparable的T類型的比較器實現。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.