2014-03-03 51 views
2

此代碼正常工作並打印出數字120.但是,如果我取消註釋主函數中的行。java數組泛型初始化

代碼拋出異常:線程「main」中的異常java.lang.ClassCastException:[Ljava.lang.Comparable;不能投射到[Ljava.lang.Double; at General.main

我搜索了一下,發現了關於java中泛型數組的幾個討論。人們承認在java中泛型數組的處理不是很好。但是我仍然對這段代碼感覺很糟糕:在不同的地方打印出一行會產生不同的結果,(正確執行與拋出異常)。

有人可以請評論這段代碼,並建議是否有任何簡單的修復與主函數中的println代碼相關的異常?

這裏是我的代碼:

public class General<Key extends Comparable<Key>> { 
    public Key[] keys;  
    @SuppressWarnings("unchecked") 
    public General(int NMAX) { 
     keys = (Key[]) new Comparable[NMAX]; 
     System.out.println(keys.length); 
    } 
    public static void main(String[] args){ 
    General<Double> g = new General<Double>(120); 
    //  System.out.println(g.keys.length); 
    } 
} 


System.out.println(g.keys.length); 
+0

是否有某些原因,您不能使用List而不是Array?也就是說,就像'私人列表 keys = new ArrayList ();' - 那麼你可以讓類'General ' –

+0

@ Elliott的調查是非常合理的。簡短的答案是示例代碼片段不是非常安全的。列表將爲您處理這個問題。 – Radiodef

+0

ArrayList肯定會解決這個問題,但我正在尋找更深入的理解爲什麼我的方法失敗,正如下面的人所解釋的。 – Chao

回答

2

你在一個看似不尋常的地方得到例外的原因是因爲擦除。的Key擦除Comparable所以這裏劇組卻從未在運行時發生的情況:

keys = (Key[]) new Comparable[NMAX]; 

但是,正如你所觀察到,當你在對象的外部檢索數組鑄造確實發生。 A Comparable[]不是Double[],所以你會得到異常。只要你不在類的外面訪問數組,你做這件事的方式可能不會造成問題。

「更安全」的習慣用法是通過聲明爲Comparable[]來使該數組非通用。那麼你:

  • 確保只有Key可以放在數組中。
  • 在檢索調用上進行未經檢查的強制轉換。

事情是這樣的:

@SuppressWarnings("rawtypes") 
public class General<Key extends Comparable<Key>> { 
    private Comparable[] keys; 

    public General(int NMAX) { 
     keys = new Comparable[NMAX]; 
    } 

    public void set(int ind, Key k) { 
     keys[ind] = k; 
    } 

    @SuppressWarnings("unchecked") 
    public Key get(int ind) { 
     return (Key)keys[ind]; 
    } 
} 

這是類型安全的,它是在JDK做它的方式。

另一種方法是讓客戶端提供的數組:

public class General<Key extends Comparable<Key>> { 
    private Key[] keys; 

    public General(Key[] keys) { 
     this.keys = keys; 
    } 
} 

你也應該考慮使用一個列表,而不是因爲他們做的這些東西對你和完全通用。你可以做new ArrayList<Key>()

+0

非常感謝您在此澄清。我遵循SedgeWick教授的算法課程,並嘗試不使用複雜的泛型來實現簡單的東西。:) – Chao

1

你可以儘量保持鍵作爲可比[]數組。

public class General<Key extends Comparable<Key>> { 
public Comparable[] keys;  // keys[i] = priority of i 

public General(int NMAX) { 
    keys = new Comparable[NMAX]; 
    System.out.println(keys.length); 
} 

public static void main(String[] args) { 
    General<Double> g = new General<Double>(120); 
    System.out.println(g.keys.length); 
} 
}