讓異常處理代碼更健壯
(給
ImportNew
加星標,提高Java技能)
來自:唐尤華
dzone.com/articles/good-exception-handling
像冠軍一樣處理異常。
哦,請不要這樣寫……
// 寫一句注釋跳過異常 try throw new "Made up"
);
}
catch
(IOException e) {// 跳過
}
// 記到日誌里,繼續處理
try
{throw
new
IOException("Made up"
);}
catch
(IOException e) {log.error(
"blah blah blah"
, e);}
// 標記 TODO,不做任何處理
try
{throw
new
IOException("Made up"
);}
catch
(IOException e) {// TODO - 處理異常 (;
}
我在各種項目中發現了這種 catch 語句。這是一種「好辦法」,可以在短期內掩蓋問題。然而幾周或幾個月後,這些代碼將成為開發人員的噩夢。 絕大多數人可不想讀日誌查問題。 因此,還是讓我們避免這種情況。
規則一:catch 語句是用來處理異常的,把異常記到日誌里然後繼續執行不算處理。
唯一的例外是,在發生異常後關閉資源(本文不討論這種情況;如果感興趣,可以參考這篇 McDowell 的博客
,雖然寫的時間比較早,但內容很不錯)。
有三種處理異常的基本模式:
轉換(translate)
、重試(retry)
和恢復(recover)
。轉換經常用於處理受檢異常(checked exception),在方法中異常無法拋出,並且無法恢復時使用。 在這種情況下,將其轉換為運行時異常(runtime exception)而後拋出是最合適的做法。接下來,運行時異常通常由框架處理。 在處理不可靠的服務時,重試非常有用,前提是重新嘗試有意義。一個很好的例子就是網路中斷重試。如果定義了這種策略,那麼就能夠恢復到正常狀態。例如,如果通過網路發送數據失敗,可以將數據寫入本地存儲。當然,這時就必須定義如何處理該文件。
此外,上面提到的模式可以組合,比如像下面這個例子如下。
// 轉換 try throw new "Made up" catch throw new
}
RuntimeException(e);
}
// 重試5次後放棄
boolean
end =false
;int
count =0
;while
(end ==false
) {try
{// 發送信息
if
(
true
) {throw
new
MessagingException("Made up"
);}
end =
true
;}
catch
(MessagingException e) {if
(count >=5
) {// 嘗試5次放棄。
throw
new
RuntimeException("was not able to send message even after five tries"
, e);}
++count;
try
{Thread.sleep(
30000
);}
catch
(InterruptedException e1) {Thread.currentThread().interrupt();
throw
new
RuntimeException(e1);}
}
}
// 恢復:如果傳輸失敗記錄到文件
try
{// 發送信息
throw
new
MessagingException("Made up"
);}
catch
(MessagingException e) {try
{// 寫文件
throw
new
IOException("Made up"
);}
catch
(IOException e1) {// 如果寫文件失敗,不再進行恢復
throw
new
RuntimeException(e1);}
}
如果一切都失敗了,那麼上面這種方法至少可以確保你能意識到問題所在。 此外,它還提供了問題的真正原因,從而讓你能快速定位問題。
祝編程快樂!
看完本文有收穫?請轉發分享給更多人
關注「ImportNew」,提升Java技能
喜歡就點「好看」唄~
TAG:ImportNew |