相關讀書筆記列表
NO.42 盡量使用標準的異常
Java平台庫中訖今為止最常被重用的異常如下:
IllegalArgumentException 參數值不合適
IllegalStateException 對於這個方法調用而言,對象的狀態不合適(如初始化不恰當)
NullPointerException 在null被禁止的情況下參數值為null
IndexOutOfBoundsException 下標越界
ConcurrentModificationException 在禁止並發修改的情況下,對象檢測到並發修改
UnsupportedOperationException 對象不支援客戶請求的方法
其它的異常也可以使用,只要確保拋出異常的條件與文檔要求一致即可。
NO.43 拋出的異常要適合於相應的抽象
高層的實現,應該捕獲低層的異常,同時拋出一個可以按照高層抽象進行解釋的異常,這種做法叫做異常轉譯(exception translation)。即如:
//exception translation!<br />try{<br /> //use lowlevel abstraction to do our bidding<br /> ...<br />}catch(LowerLevelException e){<br /> throw new HigherLevelException(...);<br />}
低層的異常被高層的異常儲存起來,且高層的異常提供一個公有的存取方法來獲得低層的異常,這種做叫做異常連結(exception chaining)。
//Exception chaining.<br />try{<br /> //use lower-level abstraction to do our bindding<br /> ...<br />}catch(LowerLevelException e){<br /> throw new HigherLevelException(e);<br />}
異常鏈的實現非常簡單,在1.4及以後版本中,可以通過Throwable來獲得支援。
//Exception chaining in release 1.4 or later<br />HigherLevelException(Throwable t){<br /> super(t);<br />}
處理來自低層的異常,
最好的做法是,在調用低層方法之前通過一些檢查等手段來確保它們會成功執行;
其次的做法是,讓高層處理這些異常,從而將高層方法的調用者與低層的問題隔離開;
一般的做法是使用異常轉譯;
如果低層方法的異常對高層也是合適的,則將其從低層傳到高層。
NO.44 每個方法拋出的異常都要有文檔
總是要單獨地聲明被檢查的異常,並且利用jacadoc的@throws標記,準確地記錄下每個異常被拋出的條件。
使用javadoc的@throws標籤積累下一個方法可能會拋出的每個未被檢查的異常,但是不要使用throws關鍵字將未被檢查的異常包含在方法的聲明中。
如果一個類中的許多方法出於同樣的原因而拋出同一個異常,那麼在該類的文檔注釋中對這個異常做文檔,而不是為每個方法單獨寫一個文檔。
NO.45 在細節訊息中包含失敗 - 捕獲資訊
為了捕獲失敗,異常資訊應該儘可能多的包含有意義的參數和域的值,如:IndexOutOfBoundsException應該包括上界、下界以及實際的下標。
NO.46 努力使失敗保持原子性
一個失敗的方法調用應該使對象保持“它在被調用之前的狀態”,方法如下:
① 使用非可變對象;
② 在可變對象上的操作,應在執行前檢查參數的有效性;
③ 寫一段恢複代碼,在執行失敗的情況下,復原到操作開始之前的狀態(不常用);
④ 在對象的一份臨時拷貝上執行操作,當完成之後,再把臨時拷貝中的結果複製給原來的對象,如Collections.sort在執行排序之前,先把它的輸入轉儲到一個數組中,這樣既能降低內迴圈的開銷,又能保證在排序失敗的時候,輸入列表將保持原樣。
NO.47 不要忽略異常
除非有特殊的需求(如動畫中的多幀映像播放),否則不要吃掉異常,至少在catch塊中包含一條說明,用來解釋為什麼忽略這個異常。簡單地將一個未被檢查的異常傳播到外界至少會使程式迅速地失敗,從而保留了有助於調試該失敗條件資訊,比異常被忽略後的一個不可預測的時刻程式失敗這種情況要強。