異常的分類
這是最直接的異常分類圖,從圖中可以看見,頂層類是Throwable,子類中分爲Error和Exception。
但是java中對這些分類還做了另外一種劃分。分爲checked和unchecked異常。
- unchecked異常:Error和RuntimeException及其子類
- checked異常:Exception中子類除了RuntimeException,其餘都是checked異常
受檢異常和非受檢異常的區別
受檢異常:java編譯器要求程序必須捕獲或者聲明拋出異常。
非受檢異常:默認情況下會得到自動處理,所以不用通常捕獲。
- 問題1:這兩種異常再什麼場景使用?
- 問題2:在哪裏處理異常?
- 問題3:如何處理這些異常?
問題1:這兩種異常在什麼場景使用?
有關於場景的問題,必然是與業務相關。關注是否是核心功能點。
問題2:在哪裏處理異常?
在哪裏處理異常,與上下文相關。不同的場景,相同的業務,對異常的處理也不相同。
例子:同樣是一個login
方法,在LoginService
中,和在BindService
- Login在LoginService中是核心功能點,在BindService中是普通功能點。所以處理異常的方式是有所區別的。
- 接下來思考,login這個方法的異常應該是什麼類型的異常?
checked
,unchecked
?- 顯然是unchecked異常,這個異常是要去處理的異常,(unchecked異常,是代碼的錯誤,需要在該方法中直接去修改),但是有些系統定義的checked異常,如何處理,看問題3。
- 那麼對這個異常到底是try…catch直接處理掉, 還是 throw向上拋出?
- 這是不能直接處理的,因爲在不同的場景中重要性不同,所以不能籠統的處理,必須返回到service業務層進行處理。所以用throw向上拋出。【如果就在本層處理掉,那麼所有的業務調用該方法,都執行了同樣的處理,這顯然是不合理的。】
問題3:如何處理異常?
同樣是與業務相關
- 如果是核心功能點,那麼顯然是要返回給用戶展示的,提示用戶重新進行操作,所以在try…catch checked異常之後要拋出一個unchecked異常,也就是RuntimeException。當然,如果方法中拋出的就已經是runtimeException,那麼就讓其自動向上處理。
- 如果是非核心功能點,那麼就自動處理掉,一般是做打印日誌處理。(試想,如果service中的記錄日誌方法異常,總不可能返回給用戶處理吧,只需要自己處理掉就行了。)
在有攔截器的情況下
自定義異常一般使用runtimeException,因爲runtimeException是自動向上拋出的。可以統一在攔截器處進行集中處理(比如日誌處理。),這樣做到了解耦,增強了健壯性。