2012-06-16 19 views
12

鑑於這種代碼:有沒有一種乾淨的方式將泛型類的類賦值給變量?

List<Integer> ints = new ArrayList<Integer>(); 

// Type mismatch: 
// cannot convert from Class<capture#1-of ? extends List> to Class<List<Integer>>  
Class<List<Integer>> typeTry1 = ints.getClass(); 

// Type safety: 
// Unchecked cast from Class<capture#2-of ? extends List> to Class<List<Integer>> 
Class<List<Integer>> typeTry2 = (Class<List<Integer>>) ints.getClass(); 

// List is a raw type. References to generic type List<E> should be parameterized 
Class<? extends List> typeTry3 = ints.getClass(); 

是否有一種方式來獲得的List<Integer>Class沒有錯誤或警告?我可以很容易地禁止警告,但是如果Java要求我取消這個有效代碼的警告,那麼我很disappoint

另一方面,如果警告抑制是唯一的方法,最安全的壓制是什麼?

+0

顯然沒有警告的免費方式,因爲擦除。 http://stackoverflow.com/questions/339699/java-generics-type-erasure-when-and-what-happens – user845279

+0

在Class對象引用中使用具體泛型類型實際上沒有意義,因爲該信息不是在被引用的對象中,所以在我的意見'類<?擴展List>'或'Class <?擴展列表>'是變量的最佳類型。我很驚訝,雖然我找不到對通配目標類型沒有警告的演員......然而,由於Class對象主要用於反射,因此您可能會很好地使用'Class ',該工作沒有警告 –

回答

5

這是一個真正的Java Catch-22。

編譯器警告你,如果你沒有一個通用的類型添加到List

// WARN: List is not typed 
Class<? extends List> typeTry3 = ints.getClass(); 

這是因爲,在大多數情況下,這真是最好鍵入您的列表。

但是,由於類型擦除,Java無法在運行時找出List的通用類型,編譯器知道這一點。因此,在沒有Class方法會返回一個類型的對象:

// ERROR: ints.getClass() doesn't return a Class<List<Integer>>, it returns a Class<List> 
Class<? extends List<? extends Integer>> var = ints.getClass(); 

所以你必須強制轉換爲類型列表。然而,正如你知道的,因爲沒有運行時類型檢查,爪哇發出警告,任何強制轉換爲類型變量:

// WARN: Casting to typed List 
Class<List<Integer>> typeTry2 = (Class<List<Integer>>) ints.getClass(); 

任何試圖解決這個問題實質上是混淆編譯器的手段,將不可避免錯綜複雜。然後

最好的辦法是去與選項B:

在另一方面,如果報警抑制是唯一的出路,什麼是最安全的壓制?

抑制此警告最安全的方法是使您的@SuppressWarnings("unchecked")註釋儘可能地本地化。把它們放在每個單獨的未經檢查的演員上方。這樣,完全清楚是誰引起了警告。

3

要做到這一點的一種方法是創建您的own class。我不確定這是否會滿足您的需求。

我不太確定你想達到什麼。所以也許wildcards就是答案。

import java.util.*; 

class Main 
{ 
     public static void main(String[] args) 
     { 
      List<Integer> list = new ArrayList<Integer>(); 
      Class<?> clazz = list.getClass(); 
      System.out.println(clazz) ; 
     } 
} 
+0

+1,沒有任何警告或錯誤,但仍然相當hacky :) – cqcallaw

+0

在我看來,像一個不合理的解決方案告訴編譯器:「我知道我會得到一個_something_類,請儘管給我沒有抱怨,儘管_you_(編譯器)可能無法推斷/保留這個_something_的類型。 –

相關問題