填坑,整理下Java的經常使用異常。正確使用異常在實際編碼中很是重要,但面試中的意義相對較小,由於對異常的理解和應用很難經過幾句話或幾行代碼考查出來,不過咱們至少應答出三點:異常類的繼承關係、經常使用異常類、經常使用異常類的使用場景,下文將圍繞這三點介紹。git
Java中,全部異常都繼承自Throwable類(一個完整可用的類)。總體上分爲Error、Exception兩個大類,Exception大類又分爲UncheckedException(繼承於RuntimeException)和CheckedException(繼承於Exception,但不繼承於RuntimeException)。github
爲了幫助理解,我在每一個類別下都給出了兩個經常使用子類,如Error包括OutOfMemoryError、AssertionError等;UncheckedException包括NullPointerException、IllegalArgumentException;CheckedException包括IOException、InterruptedException。面試畫異常類的繼承關係時,要求能清楚的說明幾個類別並分類別舉幾個經常使用的異常類。面試
下面分類別擴充一下經常使用的異常類,字典序排序:算法
類別 | 經常使用異常類 |
---|---|
Error | AssertionError、OutOfMemoryError、StackOverflowError |
UncheckedException | AlreadyBoundException、ClassCastException、ConcurrentModificationException、IllegalArgumentException、IllegalStateException、IndexOutOfBoundsException、JSONException、NullPointerException、SecurityException、UnsupportedOperationException |
CheckedException | ClassNotFoundException、CloneNotSupportedException、FileAlreadyExistsException、FileNotFoundException、InterruptedException、IOException、SQLException、TimeoutException、UnknownHostException |
須要着重理解的是UncheckedException。json
上述異常類都是很常見的,但其中幾個異常類設計的很差,須要注意:安全
經常使用異常仍是有點多,下面分別講解上述三個類別的使用場景,並在每一個類別中選一個例子進行講解。併發
Error一般描述了系統級的錯誤,而且程序猿沒法主動處理——固然,系統級錯誤也有可能由代碼間接致使,這不在咱們的討論範圍內。發生系統級錯誤的時候,系統環境已經不健康了,所以,Error不強制捕獲或聲明,也就是不強制處理,通常狀況下只須要把異常信息記錄下來(若是能記下當時的系統快照更好)。源碼分析
當可用內存不足時,會由JVM拋出OutOfMemoryError。通常由三種緣由致使:編碼
JVM拋出OutOfMemoryError前,會嘗試進行一次Full GC,若是GC後可用內存仍是不足,纔會拋出OutOfMemoryError。所以,這時程序猿必然沒法主動處理這一問題,只能等程序崩潰後再去查證緣由。線程
查證OutOfMemoryError的技巧足以單開一篇文章了,本文不做深刻。
嚴格來講,Error也能夠被劃歸UncheckedException,但咱們更習慣用UncheckedException描述運行期發生,一般因爲代碼問題直接引發的程序相關的錯誤,而且程序猿沒法主動處理。注意區分,系統級錯誤都應該用Error描述。UncheckedException發生的大部分狀況是代碼寫挫了,所以,UncheckedException也不強制捕獲或聲明,也就是不強制處理,通常狀況下記下日誌便可。
不一樣的是,若是可能,要保證UncheckedException是可控的(在異常被動拋出前檢查並主動拋出)。
JSONException就是不可控的。
NullPointerException是最多見的UncheckedException。若是在一個空指針上引用方法或變量等,則運行期會拋出NullPointerException。空指針讓程序變的不可控:若是任由空指針在程序運行期隨意傳遞、使用,咱們將沒法肯定程序的行爲,也沒法肯定捕獲NullPointerException時程序所處的狀態。
解決這一問題的方法很簡單:
前兩條原則通用於大部分UncheckedException,可參考String#toLowerCase()的例子。第三條原則須要在代碼的健壯與簡潔之間作出權衡,優先保證簡潔清晰,須要健壯再去健壯。
猴子對CheckedException的理解不到位,若是各位有更好的理解但願能交流一下。如下講猴子「不到位」的理解。
CheckedException描述了外部環境致使的不太嚴重的錯誤,程序猿應該主動處理。注意與系統級錯誤區分,系統級錯誤一般是不可恢復的。所以,CheckedException強制捕獲或聲明,程序猿必須處理。記錄日誌,包裝後再次拋出,在方法簽名中聲明,是三種最多見的作法。
同UncheckedException同樣,CheckedException也要保證是可控的。對CheckedException的可控性要求更高,不只要主動檢查,還要在捕獲到異常時,做出合適的處理。
不過,猴子認爲大量CheckedException的存在就是個錯誤。好比FileAlreadyExistsException,更應該由用戶主動檢查發現,而不該該依賴於異常。對於能夠處理的異常,本質上至關於控制流問題,用異常去表達反而讓控制流變模糊。不過有時候猴子寫小項目,也會爲了簡化代碼,直接將相關異常聲明在方法簽名中,並一路聲明幹到main方法。恩,everything is a trade-off。
產生IOException的緣由很是多,但不少時候咱們並不關心細節緣由,由於文件系統是一個不太可控的因素,這時咱們能夠以IOException爲粒度處理;某些須要關心細節的異常狀況,則應使用IOException的子類,以分狀況處理。
前面總結的FileAlreadyExistsException、FileNotFoundException、UnknownHostException等,都是IOException的子類。這三種異常剛好都是能夠處理的。
挖坑,InterruptedException也至關重要,後面要專門寫一篇來整理。
實際的編碼工做中,咱們應正確的使用異常表達代碼設計,並儘量使用JDK提供的異常類。JDK內置了很是多的異常類,咱們只須要掌握一些經常使用的異常類,而後觸類旁通。
本文連接:Java經常使用異常整理
做者:猴子007
出處:monkeysayhi.github.io
本文基於 知識共享署名-相同方式共享 4.0 國際許可協議發佈,歡迎轉載,演繹或用於商業目的,可是必須保留本文的署名及連接。