2014-01-14 36 views
2

初學Java編碼器在這裏。這裏的代碼:未經檢查的演員 - 我應該壓制這個嗎?

private ArrayList<Rectangle> rectangles; 
try { 
     InputStream IS = MyClass.class.getResourceAsStream("file.dat"); 
     ObjectInputStream input = new ObjectInputStream(IS); 
     rectangles = (ArrayList<Rectangle>) input.readObject(); 
} catch (IOException | ClassNotFoundException ex) { 
     System.out.println(ex); 
} 

Netbeans告訴我,這是一個未經檢查的演員。谷歌告訴我,我應該儘量避免這個警告,而不是壓制它,那麼我該如何去做呢?這個程序應該讀取的唯一文件確實包含一個ArrayList,如果沒有,我很好,只是捕獲這些異常。此外,如果我對char [] [](從OIS讀取並嘗試投射)執行相同操作,netbeans不會有任何問題。這是爲什麼?我認爲這仍然是一個不受控制的演員。

回答

2

如果你知道爲什麼它在那裏,你應該只禁止警告。在這種情況下,因爲它聽起來像你理解這個問題,並正在採取措施來處理它,然後抑制它可能是好的。但是,如果你是在做警告走背水戰,唯一的方法我發現這樣做,在這種情況下是做這樣的事情:

public class ListOfRectangles extends ArrayList<Rectangle> {} 

然後用ListOfRectangles爲您的數據類型序列化往返於該文件。

編譯器與char [] []合適而不是ArrayList<Rectangle>的原因是因爲Java泛型稱爲擦除的概念。這意味着對於泛型類型(如ArrayList),參數化類型(本例中爲Rectangle)實際上不在字節碼中。它只在編譯期間出現,因此編譯器可以仔細檢查你的工作。數組並非如此。

有一個更深入瞭解泛型here

1

有時,避免演員陣容根本不可能或太難。通過任何方式儘量避免總是分配檢查類型。但是,如果你不能,那麼只是壓制它。恕我直言。

在這種情況下看起來完全合法的壓制它。這比返回Object要好。

1

總是試圖避免這個警告,而不是壓制它,這樣可以降低運行時錯誤的機率。

+0

運行時錯誤是受到檢查或未檢查轉換的危險。唯一的區別是該錯誤的確切位置。 –

1

,如果不能避免,如果可能的話,文件。下面是喬希布洛赫建議記錄的方式(有效的Java,第二版,第26項):不是全功能

private ArrayList<Rectangle> rectangles; 
try { 
     InputStream IS = MyClass.class.getResourceAsStream("file.dat"); 
     ObjectInputStream input = new ObjectInputStream(IS); 

     //The input stream is definitely an ArrayList<Rectangle> 
     //I know this because............... 
     @SuppressWarnings("unchecked") 
     ArrayList<Rectangle> rectangles2 = (ArrayList<Rectangle>) input.readObject(); 
     rectangles = rectangles2; 

} catch (IOException | ClassNotFoundException ex) { 
     System.out.println(ex); 
} 

這本地化的抑制來的幾行代碼。

+0

假設你有修復的錯誤。你會相信一個評論,然後走開嗎?如果你的答案是「是」,那麼你不能完成調試任務。換句話說,忘記評論。 –

+1

它最好是一個該死的好和有用的評論,否則它*不*值得信賴。如果它沒有幫助調試,它不應該在那裏。 – aliteralmind

+0

評論和代碼有他們自己獨立的生活。我是否應該去挖掘git歷史記錄來首先追蹤添加註釋的原始提交,然後通過任何修改來決定每個修改是否保留註釋中解釋的屬性?沒辦法,我花時間親自檢查代碼的功能。事實上,需要練習才能學會如何徹底和完全忽略**評論,以便在閱讀代碼時引導你誤入歧途。這對我來說是一種傷害。 –

0

抑制警告可能是合法的。例如,如果您完全確信序列化格式,則可以將其抑制。但是,如果您不確定,因爲其他人制作了序列化格式,或者您認爲格式可能會隨着時間的推移而演變,您可以在不執行任何不安全轉換的情況下驗證內容。

List<?> untyped = (List<?>) input.readObject(); 
List<Rectangle> rectangles = new ArrayList<>(untyped.size()); 
for (Object obj : untyped) 
    rectangles.add((Rectangle) obj); 

這將確保如果一個元素是不是Rectangle,所產生的ClassCastException將立即某處後拋出,在顯式轉換的網站,而不是,在執行沒有明顯蒙上了點。