2009-10-02 65 views
7

我有以下代碼使用泛型導致未檢查轉換警告

String innerText = null; 
innerText = this.getException(detail.getChildElements()); 

導致此警告

類型安全:類型Iterator的表達需要選中轉換成符合 到迭代器

參考方法是

private String getException(Iterator<OMElementImpl> iterator) { ... } 

另一種方法getChildElements()位於我無法觸及的JAR文件中。沒有其他警告或錯誤。

從谷歌搜索,似乎想擺脫這種警告的通常的方法是

@SuppressWarnings("unchecked") 
String innerText = this.getException(detail.getChildElements()); 

因爲編譯器不能保證提前安全,但我寧願避免使用SuppressWarnings如果可能......有更好的方法嗎?

編輯:getChildElements()是記錄here

+5

只是很高興Java泛型允許你的代碼編譯。我個人會在那裏留下警告 - 這是一個完全有效的警告。 – 2009-10-02 15:11:31

回答

16

可以抑制警告,但如果你這樣做,你是在第三方庫依託100%,並放棄Java的泛型類型的保證:即在運行時產生的任何ClassCastException都會在顯式轉換時發生。

我們的編碼標準是爲了抑制警告只有當我們能夠證明的代碼是類型安全—和我們對待包作爲黑盒外的任何電話,並且不依賴於有關的內容有任何意見原始的收藏。所以,抑制是非常罕見的。通常,如果代碼是類型安全的,編譯器可以確定它,但有時我們必須給它一些幫助。少數例外涉及不從私有上下文中「逃脫」的泛型類型的數組。

如果您不完全信任第三方庫,請創建一個新的集合,並在將其添加到OMEElementImpl後添加內容。這樣,如果庫中存在一個錯誤,你馬上就會發現它,而不是讓一些代碼在時間和空間上遠離一個ClassCastException

例如:

Iterator<?> tmp = detail.getChildElements(); 
Collection<OMElementImpl> elements = new ArrayList<OMElementImpl>(); 
while (tmp.hasNext()) 
    elements.add((OMElementImpl) tmp.next()); /* Any type errors found here! */ 
String innerText = getException(elements.iterator()); 

記住,仿製藥並沒有發明使代碼看起來很漂亮,需要更少的打字!泛型的承諾是這樣的:如果您的代碼在沒有警告的情況下編譯,則保證其是類型安全的。就是這樣。當忽略或抑制警告時,沒有投射操作員的代碼可能會神祕地提起ClassCastException


更新:在這種情況下,尤其是,它似乎非常危險的假設的getChildElements結果是OMElementImpl一個迭代器。充其量,你可能會認爲他們是OMElement,而這只是從班級暗示的,而不是特別的方法。

+0

驗證這樣的第三方庫返回的集合的內容是很好的建議。 – 2009-10-02 15:24:38

+0

作爲創建新集合的替代方法,請參閱Google Collections中的「Iterables.transform」http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Iterables.html#transform( java.lang.Iterable,%20com.google.common.base.Function) – 2009-10-02 15:36:16

+0

嗯,我是一個新的初級開發人員,並且已經確信可以在這個特定情況下做出假設;我(和我的技術主管,就此而言)只是看不到這個小小的警告圖標。 + 1 /被接受爲提供良好的一般建議,但。 – Pops 2009-10-06 13:08:09