2010-10-14 26 views
6

我已經實現了這個功能:的Java:未選中從X轉換爲Y /如何實現castOrNull

static <X,Y> Y castOrNull(X obj) { 
    try { 
    return (Y)obj; 
    } 
    catch(ClassCastException e) { 
    return null; 
    } 
} 

這使我的編譯器警告:

Type safety: Unchecked cast from X to Y 

我不明白究竟。 try/catch是不是我在這裏做檢查?我可以忽略警告嗎?

我的功能是否按預期工作?我將如何正確實施它?

我也嘗試了obj instanceof Y檢查,但由於Java處理泛型的方式,這不起作用。

順便說一句,這個功能對我來說似乎很有用(使其他代碼更清潔)。我不知道Java中是否已經存在這樣的函數?


一個例子,我想使用它:

void removeEmptyRawStrings() { 
     for(Iterator<Entity> e = entities.iterator(); e.hasNext();) { 
      RawString s = castOrNull(e.next()); 
      if(s != null && s.content.isEmpty()) e.remove(); 
     } 
    } 

我有一樣的情況下,這些常常在我的代碼。我認爲這比其他任何東西都更具可讀性和簡單性。但如果你有任何關於如何使代碼更簡單的問題,請給我一個更好的建議。

+0

今天我在想這個警告,是否有可能有一個檢查過的演員,但我認爲你不能這樣做。 – DeliveryNinja 2010-10-14 13:42:28

回答

11

所以這裏的問題是,用於動態鑄造的通用參數Y被視爲Object。它永遠不會拋出CCE。你得到的CCE拋出的方法叫做方法,因爲你打破了靜態類型的安全。

而且X是完全沒有意義的位置:

幾乎可以肯定,正確的解決辦法是不要試圖像這樣的東西。 null不好。鑄造不好。

但是,如果你有決心寫廢話,你可以通過Class對象:

public static <T> T evilMethod(Class<T> clazz, Object obj) { 
    try { 
     return clazz.cast(obj); 
    } catch (ClassCastException exc) { 
     return null; 
    } 
} 
+0

啊,很好的回答! – aioobe 2010-10-14 13:51:52

+0

謝謝。我擴展了我的問題來展示我想要使用它的位置/方式。你能否描述爲什麼這樣做是件壞事?我怎樣才能使代碼更簡單,而不使用這樣的功能? – Albert 2010-10-14 13:57:02

+5

'if(clazz.isInstance(obj)'而不是捕捉CCE呢? – 2010-10-14 13:58:00

1

您可以取消此警告在此方法中,如果你肯定知道,這不是一個問題,通過與@SuppressWarnings("unchecked")

4

標註它,我不能完全肯定預期它會工作。 (取決於你期望當然:-)的什麼,但對於在java.lang.ClassCastExceptionideone實例結果)這段代碼:

public class Main { 

    public static void main(String[] args) { 
     Integer o = Main.<String, Integer>castOrNull("hello"); 
    } 


    public static <X, Y> Y castOrNull(X obj) { 
     try { 
      return (Y) obj; 
     } catch (ClassCastException e) { 
      return null; 
     } 
    } 
} 

@湯姆Hawtin了the "correct" solution

0

由於其中設計了這個代碼不會在所有的工作方式Java泛型的。泛型僅用於編譯時類型檢查,因爲類在運行時不使用泛型類型信息。

您的代碼將被編譯成這樣:

static Object castOrNull(Object obj) { 
    try { 
    return (Object)obj;//FAIL: this wont do anything 
    } 
    catch(ClassCastException e) { 
    return null; 
    } 
} 

演員到對象將永遠不會失敗,並且編譯的代碼必須出現在編譯時泛型類型的訪問權限。由於演員陣容沒有按照它的方式發生,所以你會收到一個未經檢查的操作的警告。

+1

有些誤導評論在你的代碼中;) – aioobe 2010-10-14 14:10:39

相關問題