摘要: 簡單實用的建議。java
Fundebug經受權轉載,版權歸原做者全部。數據庫
在Java語言中,異常從使用方式上能夠分爲兩大類:網絡
在Java中類的異常結構圖以下:性能
在異常處理時的幾點建議:spa
catch (SomeException e) { return null; }
public void foo() throws Exception { //錯誤的作法}
public void foo() throws MyBusinessException1, MyBusinessException2 { //正確的作法}
一味的使用Exception,這樣就違背了可檢查異常的設計初衷,由於調用都不知道Exception究竟是什麼,也不知道該如何處理。捕獲異常時,也不要捕獲範圍太大,例如捕獲Exception,相反,只捕獲你能處理的異常,應該處理的異常。即然方法的聲明者在方法上聲明瞭不一樣類型的可檢查異常,他是但願調用者區別對待不一樣異常的。debug
永遠不要捕獲Throwable,由於Error也是繼承自它,Error是Jvm都處理不了的錯誤,你能處理?因此基於有些Jvm在Error時就不會讓你catch住。設計
不要丟失異常棧,由於異常棧對於定位原始錯誤很關鍵日誌
catch (SomeException e) {throw new MyServiceException("Some information: " + e.getMessage()); //錯誤的作法}
必定要保留原始的異常:code
catch (SomeException e) { throw new MyServiceException("Some information: " , e); //正確的打開方式}
catch (SomeException e) { LOGGER.error("Some information", e); throw e; }
這樣的log沒有任何意義,只會打印出一連串的error log,對於定位問題無濟於事。orm
若是在finally中拋出異常,將會覆蓋原始的異常,若是finally中真的可能會發生異常,那必定要處理並記錄它,不要向上拋。
要給異常添加上有用的上下文信息,單純的異常棧,沒有太大意義
異常界著名的原則,錯誤發生時及早拋出,而後在得到因此所有信息時再捕獲處理.也能夠理解爲在低層次拋出的異常,在足夠高的抽象層面才能更好的理解異常,而後捕獲處理。
如網絡鏈接,數據庫操做等,能夠用try finally來作clean up的工做。
咱們老是不經意間這麼作了,這樣使得代碼變動醜陋,使得正常業務邏輯和錯誤處理混淆不清;並且也可能會帶來性能問題,由於異常是個比較重的操做。
在最邊緣的入口校驗用戶的輸入,這樣使得咱們不用再更底層邏輯中到處校驗參數的合法性,能大大簡化業務邏輯中沒必要要的異常處理邏輯;相反,在業務中不若是擔憂參數的合法性,則應該使用衛語句拋出運行時異常,一步步把對參數錯誤的處理推到系統的邊緣,保持系統內部的清潔。
LOGGER.debug("enter A");LOGGER.debug("enter B"); //錯誤的方式
LOGGER.debug("enter A, enter B");//正確的方式