標籤:資訊 通過 錯誤頁面 ted web 規範 service -- stack
本篇不打算冗長介紹各種異常,唯寫出通用的應該遵循的異常處理規範(個人理解,如有錯誤歡迎指正)
1. 檢查異常(checked exception),通常見到的有SQLException,IOException,InterruptedException,ConnectTimeOutException,ClassNotFoundException等等。這些異常往往是由於資料庫,網路和資源問題導致的,不是程式本身正常啟動並執行情況。這些異常被認為是可以恢複的,比如網路異常可以通過重試幾次有可能就解決了。這類異常要求程式員必須捕獲並作處理,程式員的具體處理還是要根據業務情況而定。 非檢查異常(unchecked exception),常見的有NullPointerExceprion,OutOfBoundsException,IllegalArgumentExcetion,NumberFormatException等(一般這類異常繼承自RuntimeException),這些一般是程式內部的,由於資料格式的問題產生的非正常情況,理論上是不應該發生的,而我們也的確可以通過某種方式避免一些非檢查異常(數組長度判斷,非空判斷等)。非檢查異常不要求程式員必須捕獲,有時候函數頭會指明拋出的非檢查異常(但是不要求一定捕獲),有時候只在api的注釋裡面說明可能拋出的異常。這個是api設計的不一致問題。 java區分這兩種異常,在一些時候顯得沒那麼必要,檢查異常要求強制try-catch,以及直接在函數頭上聲明出來,會讓代碼很難看。因此一般項目中使用的都是非檢查異常,有些底層的檢查異常最後也會被轉譯為非檢查異常。非檢查異常不會汙染介面,但是還是需要處理。 2. 不要使用異常做流程式控制制 比如不對除數做判斷,當發生異常時,再得出除數等於0或返回失敗。或者當某段代碼異常了表示進入某個分支,沒有異常就走另外一分支。或者通過異常跳出迴圈。因為異常的try-catch是消耗資源的做法,異常針對的是非正常情況,不應該與正常的業務代碼混用。 3. 異常如果能處理就內部處理了,如果不能處理就拋給調用者,而不應該catch了異常,然後列印了堆棧資訊就完了。 異常能處理,比如發生了檢查異常,我們可以重試多次,如果多次仍然失敗,就拋出;或者說一段代碼異常,沒有更高一級的調用者能夠處理了,再拋出就拋給虛擬機器了,此時要處理它;或者說某段代碼異常就可以認定這個任務失敗了,這時就可以處理之做狀態變更。 catch了異常不處理,只列印,導致的問題就是調用者正常調用了這個方法,也正常返回了,覺得應該沒有問題了,但是實際上方法內部異常了。這時候調用者拿到錯誤的資料就會產生非常嚴重的後果。雖然有日誌列印,但是實際上業務上認為成功了,除非任務失敗,否則如果沒有人檢查日誌就不會有人發現這段錯誤。 4. 保留異常現場 異常發生時,如果確定要catch處理它,除了記錄堆棧資訊(使用日誌的項目中,需要用logger記錄,而不要e.printStackTrace(),此外,我見過只記錄e.getMessage()的,發生錯誤之後,我只能看到一個null 指標異常,而看不到哪一行null 指標了),還要保留異常現場。也就是說發生異常時正在做什麼操作,操作的輸入參數輸出參數是怎樣的(日誌格式強烈建議正常化,不然不統一的格式看起來很難受)。方便從參數中發現異常原因,排查問題。 5. 不要有過大的try塊 try-catch是比較消耗資源的做法(不清楚JVM的實現,有機會再研究,但是直觀地看,程式要保留異常堆棧資訊,監控代碼是否異常,應該不是輕鬆的事情), 所以只針對可能拋出異常的代碼try-catch,try-catch中不應該有太多無關操作。比如異常做狀態修改,完全可以用一個boolean值在catch完之後再做記錄。 6. 不要從頭到尾只用一種異常 不要只用exception或者RuntimeException處理所有的異常。程式當中應該區分不同模組和不同層的異常,比如系統異常業務異常,dao異常service異常,方便出錯的時候定位問題。另外,對異常可以使用編碼來記錄異常類型和異常說明。這樣可以用一個類/設定檔,來對異常進行管理。如果要修改異常的表示方式或者文字說明,也不用每個類裡面亂找。將一些一些api異常或者底層的異常,轉移為業務異常(catch之後new一個業務異常),也是經常有的。 7. 對try塊中申請的資源,應該要在finally中釋放掉,java7提供了try(聲明資源語句),但總之資源都應該保證退出方法時被釋放。 8. 記住異常是非正常情況,如果能夠避免就盡量避免,異常只是一種保障機制,不代表我們可以無視商務邏輯和演算法,隨便寫,寫完catch就行了。 對於一些可以規避的異常(null 指標,非法數字格式,下標越界等),可以通過程式判斷來避免。對於web的控制層異常,需要轉譯異常,跳轉到錯誤頁面,或者是提示前台【內部錯誤】,不要將堆棧資訊也顯示到前台。 ---------------------------以上----------------------------
java 異常小結