異常處理
1. 【強(qiáng)制】不要捕獲 Java 類庫中定義的繼承自 RuntimeException 的運(yùn)行時異常類,如:IndexOutOfBoundsException / NullPointerException,這類異常由程序員預(yù)檢查來規(guī)避,保證程序健壯性。
正例: if(obj != null) {...}
反例: try { obj.method() } catch(NullPointerException e){...}
2. 【強(qiáng)制】異常不要用來做流程控制,條件控制,因?yàn)楫惓5奶幚硇时葪l件分支低。
3. 【強(qiáng)制】對大段代碼進(jìn)行 try - catch ,這是不負(fù)責(zé)任的表現(xiàn)。 catch 時請分清穩(wěn)定代碼和非穩(wěn)定代碼,穩(wěn)定代碼指的是無論如何不會出錯的代碼。對于非穩(wěn)定代碼的 catch 盡可能進(jìn)行區(qū)分異常類型,再做對應(yīng)的異常處理。
4. 【強(qiáng)制】捕獲異常是為了處理它,不要捕獲了卻什么都不處理而拋棄之,如果不想處理它,請將該異常拋給它的調(diào)用者。最外層的業(yè)務(wù)使用者,必須處理異常,將其轉(zhuǎn)化為用戶可以理解的內(nèi)容。
5. 【強(qiáng)制】有 try 塊放到了事務(wù)代碼中, catch 異常后,如果需要回滾事務(wù),一定要注意手動回滾事務(wù)。
6. 【強(qiáng)制】 finally 塊必須對資源對象、流對象進(jìn)行關(guān)閉,有異常也要做 try - catch 。
說明:如果 JDK 7,可以使用 try - with - resources 方式。
7. 【強(qiáng)制】不能在 finally 塊中使用 return , finally 塊中的 return 返回后方法結(jié)束執(zhí)行,不會再執(zhí)行 try 塊中的 return 語句。
8. 【強(qiáng)制】捕獲異常與拋異常,必須是完全匹配,或者捕獲異常是拋異常的父類。
說明:如果預(yù)期對方拋的是繡球,實(shí)際接到的是鉛球,就會產(chǎn)生意外情況。
9. 【推薦】方法的返回值可以為 null ,不強(qiáng)制返回空集合,或者空對象等,必須添加注釋充分說明什么情況下會返回 null 值。調(diào)用方需要進(jìn)行 null 判斷防止 NPE 問題。
說明:本規(guī)約明確防止 NPE 是調(diào)用者的責(zé)任。即使被調(diào)用方法返回空集合或者空對象,對調(diào)用者來說,也并非高枕無憂,必須考慮到遠(yuǎn)程調(diào)用失敗,運(yùn)行時異常等場景返回 null 的情況。
10. 【推薦】防止 NPE ,是程序員的基本修養(yǎng),注意 NPE 產(chǎn)生的場景:
1 ) 返回類型為包裝數(shù)據(jù)類型,有可能是 null ,返回 int 值時注意判空。
反例: public int f() { return Integer 對象}; 如果為 null ,自動解箱拋 NPE 。
2 ) 數(shù)據(jù)庫的查詢結(jié)果可能為 null 。
3 ) 集合里的元素即使 isNotEmpty ,取出的數(shù)據(jù)元素也可能為 null 。
4 ) 遠(yuǎn)程調(diào)用返回對象,一律要求進(jìn)行 NPE 判斷。
5 ) 對于 Session 中獲取的數(shù)據(jù),建議 NPE 檢查,避免空指針。
6 ) 級聯(lián)調(diào)用 obj . getA() . getB() . getC(); 一連串調(diào)用,易產(chǎn)生 NPE 。
11. 【推薦】在代碼中使用“拋異?!边€是“返回錯誤碼”,對于公司外的 http / api 開放接口必須使用“錯誤碼” ; 而應(yīng)用內(nèi)部推薦異常拋出 ; 跨應(yīng)用間 RPC 調(diào)用優(yōu)先考慮使用 Result 方式,封裝 isSuccess 、“錯誤碼”、“錯誤簡短信息”。
說明:關(guān)于 RPC 方法返回方式使用 Result 方式的理由:
1 ) 使用拋異常返回方式,調(diào)用方如果沒有捕獲到就會產(chǎn)生運(yùn)行時錯誤。
2 ) 如果不加棧信息,只是 new 自定義異常,加入自己的理解的 error message ,對于調(diào)用端解決問題的幫助不會太多。如果加了棧信息,在頻繁調(diào)用出錯的情況下,數(shù)據(jù)序列化和傳輸的性能損耗也是問題。
12. 【推薦】定義時區(qū)分 unchecked / checked 異常,避免直接使用 RuntimeException 拋出,更不允許拋出 Exception 或者 Throwable ,應(yīng)使用有業(yè)務(wù)含義的自定義異常。推薦業(yè)界已定義過的自定義異常,如: DAOException / ServiceException 等。
13. 【參考】避免出現(xiàn)重復(fù)的代碼 (Don ’ t Repeat Yourself) ,即 DRY 原則。
說明:隨意復(fù)制和粘貼代碼,必然會導(dǎo)致代碼的重復(fù),在以后需要修改時,需要修改所有的副本,容易遺漏。必要時抽取共性方法,或者抽象公共類,甚至是共用模塊。
正例:一個類中有多個 public 方法,都需要進(jìn)行數(shù)行相同的參數(shù)校驗(yàn)操作,這個時候請抽取:
private boolean checkParam(DTO dto){...}