1. 程式人生 > >JAVA 專案中常見的異常處理約定或準則

JAVA 專案中常見的異常處理約定或準則

轉自:https://www.cnblogs.com/molao-doing/articles/6401705.html

異常的定義

在《java程式設計思想》中這樣定義 異常:阻止當前方法或作用域繼續執行的問題。雖然java中有異常處理機制,但是要明確一點,決不應該用"正常"的態度來看待異常。絕對一點說異常就是某種意義上的錯誤,就是問題,它可能會導致程式失敗。之所以java要提出異常處理機制,就是要告訴開發人員,你的程式出現了不正常的情況,請注意。異常是程式處理意外情況的機制,當程式發生意外時,我們需要儘可能多的得到意外的資訊,包括髮生的位置,描述,原因等等。
但是在專案中往往要把異常處理好並非易事,異常的本意是好的,讓我們試圖修復程式,但是如果事先沒有約定或者開發人員沒有對異常有深刻的理解。往往會使專案變得越來約糟糕!甚至會造成無法挽回的錯誤。比如清理工作對於我們來說是必不可少的,因為如果一些消耗資源的操作,比如IO,JDBC。如果我們用完以後沒有及時正確的關閉,那後果會很嚴重,這意味著記憶體洩露等。這裡總結了一些異常處理機制的常見約定,希望對異常有更加深入的理解,以避免在今後的專案中儘量少採坑。

附Java異常類層次結構圖



 

在專案中的一些對異常處理的相關約定或準則

1、不要捕獲 Java 類庫中定義的繼承自 RuntimeException 的執行時異常類,如:IndexOutOfBoundsException / NullPointerException,這類異常由程式設計師預檢查違法來規避,保證程式健壯性。

正例: if(obj != null) {...} 
反例: try { obj.method() } catch(NullPointerException e){...} 

2、異常不要用來做流程控制,條件控制,因為異常的處理效率比條件分支低。這個坑大家要注意了。

3、對大段程式碼進行 try-catch,這是不負責任的表現。 catch 時請分清穩定程式碼非穩定程式碼,穩定程式碼指的是無論如何不會出錯的程式碼。對於非穩定程式碼的 catch 儘可能進行區分異常型別,再做對應的異常處理。

4、捕獲異常是為了處理它,不要捕獲了卻什麼都不處理而拋棄之,如果不想處理它,請將該異常拋給它的呼叫者。最外層的業務使用者,必須處理異常,將其轉化為使用者可以理解的內容。
5、有 try 塊放到了事務程式碼中, catch 異常後,如果需要回滾事務,一定要注意手動回滾事務。

6、finally 塊必須對資源物件、流物件進行關閉,有異常也要做 try-catch。說明: 如果 JDK7,可以使用 try-with-resources 方式。
7、不能在 finally 塊中使用 return, finally 塊中的 return 返回後方法結束執行,不會再執行 try 塊中的 return 語句。

8、捕獲異常與拋異常,必須是完全匹配,或者捕獲異常是拋異常的父類。說明: 如果預期對方拋的是繡球,實際接到的是鉛球,就會產生意外情況。

9、方法的返回值可以為 null,不強制返回空集合,或者空物件等,必須添加註釋充分說明什麼情況下會返回 null 值。呼叫方需要進行 null 判斷防止 NPE 問題。
說明: 本規約明確防止 NPE 是呼叫者的責任。即使被呼叫方法返回空集合或者空物件,對呼叫者來說,也並非高枕無憂,必須考慮到遠端呼叫失敗,執行時異常等場景返回 null 的情況。

10、在程式碼中使用“拋異常”還是“返回錯誤碼”,對於公司外的 http/api 開放介面必須使用“錯誤碼”; 而應用內部推薦異常丟擲; 跨應用間 RPC 呼叫優先考慮使用 Result 方式,封裝 isSuccess、 “錯誤碼”、 “錯誤簡簡訊息”。

11、定義時區分 unchecked / checked 異常,避免直接使用 RuntimeException 丟擲,更不允許丟擲 Exception 或者 Throwable,應使用有業務含義的自定義異常。推薦業界已定義過的自定義異常,如: DAOException / ServiceException 等。
12、對於執行時異常,我們不要用try...catch來捕獲處理,而是在程式開發除錯階段,儘量去避免這種異常,一旦發現該異常,正確的做法就會改程序序設計的程式碼和實現方式,修改程式中的錯誤,從而避免這種異常。捕獲並處理執行時異常是好的解決辦法,因為可以通過改進程式碼實現來避免該種異常的發生。對於受檢查異常,沒說的,老老實實去按照異常處理的方法去處理,要麼用try...catch捕獲並解決,要麼用throws丟擲!對於Error(執行時錯誤),不需要在程式中做任何處理,出現問題後,應該在程式在外的地方找問題,然後解決。