各個應用難免比會遇到異常;如何處理異常,各個業務線都有自己的想法和做法;整理了一下網上的通用辦法。抛磚引玉,期待給出更有用的意見,共建沒有異常的系統。
隻對異常的情況,才使用異常
不要把異常機制用來做【判斷條件】【循環】等其他邏輯的輔助,異常隻做好異常的事情
程式的真實異常使用RuntimeException,可恢複的異常使用Exception具體子類(),不用動ERROR
1:api應該讓使用者面向 可恢複的異常變成,盡量處理所有異常(如TimeoutException重試)需要catch;最好抛出異常時,把恢複方案寫出來。
2:RuntimeException用于前提條件錯誤了,不可恢複。需要處理的情況。(如IndexOutOfBoundersException)不應該catch;
3:ERROR是java内建的,夠用一般不要繼承,非要繼承請繼承RuntimeException;
4:自定義異常,或者抛出異常,不要直接使用Throwable接口。直接Error,RuntimeExcetption,Exception,這樣會更加清洗,不迷惑開發。
避免不必要的受檢異常
這種異常雖然可靠,但是需要反複catch處理。(換位思考:如果一個異常抛出後,api的使用者除了列印日志,沒有其他恢複手段,就用RunTimeException,如參數錯誤了。怎麼玩也沒有用)
優先使用标準異常
不要重造輪子,增加代碼可讀性。
IllegalArgumentException:參數不對
IllegalStateException:對象還未初始化好
NullPointException:企圖調用空的對象
ConcurrentModificationException:單線程的對象,被多線程通路時
UnsupportOperationException:某個實作類不打算實作接口的某個方法時
IndexOutOfBoundersException:數組下标越界。
盡量做異常轉譯
如 get 方法的實作 遇到到了NoSuchElementException,catch它并抛出IndexOutOfBoundsException(NoSuch)。使得異常符合get 的寓意(想象一下再get的時候傳回一個NoSuchElementException的迷惑感)(java的标準異常大多支援 異常鍊,是以還是可以找到NoSuchElementException的原因的)
一個方法如果顯示throws異常,都要寫好注釋@thows
方法的注釋,明确兩個點,1:什麼情況會觸發這個異常,2:觸發這個異常該如何解決。
方法不要顯示的抛出Exception 甚至Throwable等異常的超"累"。一時爽,把所有的異常都寫清楚。
Runtime類型的異常也做到文檔細緻化的話,不要在方法中顯示抛出運作是異常,也不要在注釋中 throws。
在接口中一定要做好上訴的事情,接口是不僅是調用者的參考,還是實作類的參考。
認真填寫Exception的msg字段
有的異常往往難以複現,是以我們在将現場的更多相關的資訊(參數和過程變量等),傳遞給msg字段。
使異常調用不要産生效果(如db變化等)
當出現異常,盡量使得本次調用不産生任何有效的結果,盡量做到本次調用可忽略,保持資料安全
1:通過檢查參數可靠性,避免異常發生
2: 通過編寫對應修複復原方法,處理異常。
3: 使得對象都是不可修改
4: 如果一個異常是無法保持原子性,最好文檔寫清楚。(如concurrentmodificationsException,基本已經把對象改歪了,不可恢複。)
不要catch異常後啥也不幹
顯而易見,這麼做,當故障發生時,将災難臨頭,如本來可以打出堆棧,開發通過日志可以知道hbase挂了,被catch了啥也看不到。導緻使用者的資料怎麼都出不來。