在Java中,當你須要統一處理異常的時候,你是會選擇catch (Exception),仍是直接catch (Throwable)?java
#Java的異常體系spring
#應該catch什麼 其實只要是Throwable和其子類都是能夠throw和catch的,那麼若是在須要統一處理異常的地方,咱們應該catch (Throwable th) 仍是 catch (Exception)呢?json
這兩種處理的區別在於,catch throwable會把Error和其餘繼承Throwable的類捕捉到。而catch Exception只會捕捉Exception極其子類,捕捉的範圍更小。先不考慮有其餘的類繼承了Throwable的狀況下(附錄A),第一種catch至關於比第二種catch多捕捉了把Error和其子類。服務器
那麼究竟Error是否須要捕捉呢?JDK中Error類的的註釋(以下)裏提到過,Error是一種嚴重的問題,應用程序不該該捕捉它。網絡
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it.app
A method is not required to declare in its throws clause any subclasses of Error that might be thrown during the execution of the method but not caught, since these errors are abnormal conditions that should never occur.框架
Java Lanuage Spec 7 中也提到:Error繼承自Throwable而不是繼承自Exception,是爲了方便程序可使用 "catch (Exception)"來捕捉異常而不會把Error也捕捉在內,由於Exception發生後能夠進行一些恢復工做的,可是Error發生後通常是不可恢復的。ui
The class Error is a separate subclass ofThrowable, distinct from Exception in the class hierarchy, to allow programs to use the idiom "} catch (Exception e) { " (§11.2.3) to catch all exceptions from which recovery may be possible without catching errors from which recovery is typically not possible.線程
已經不難看出,Java自己設計思路就是但願你們catch Exception就足夠了,若是有Error發生,catch了也不會有什麼做用(附錄B)。設計
#引伸,如何設計異常體系? 如何設計異常體系要根據你的項目的狀況,類庫框架,應用程序的異常設計方式都會有一些區別。下面簡單談談我的對異常設計的一些見解
##類庫/框架
##應用程序
#附錄A:是否應該直接繼承Throwable來擴展新的異常? 我的認爲異常都應該繼承自Exception或者RuntimeException,並且Java自己對Exception和Error的規劃就很清晰了,Java本身類庫中沒有異常是直接繼承自Throwable的。
#附錄B:Error能夠catch嗎? 能夠catch了後作些其餘處理嗎? Error是能夠catch的,並且也能夠向常規Exception同樣被處理,並且就算不捕捉的話也只是致使當前線程掛掉,其餘線程仍是能夠正常運行,若是有須要的話捕捉Error以後也能夠作些其餘處理。可是Error是一種系統內部的錯誤,這種錯誤不像Exception同樣是多是程序和業務上的錯誤是能夠恢復的。
假設進行網絡鏈接操做的時候,IOException 發生了,多是網絡中斷,我能夠再嘗試幾回。
假設OutOfMemoryError發生了,就算被捕捉了,能夠有什麼手段讓程序正常運行下去嗎? 假設ExceptionInInitializerError發生了,類沒法被正常初始化,這個是能夠經過捕捉來恢復的嗎?