1. 程式人生 > >Java異常體系概述

Java異常體系概述

## Java的異常體系結構 ![](https://img2020.cnblogs.com/blog/908629/202101/908629-20210104164312629-1344091298.png) Java異常體系的根類是 Throwable, 所以當寫在java程式碼中寫throw丟擲異常時,後面跟的物件必然是Throwable或其子類的物件。 其中Exception異常是指一些可以恢復的異常, 例如常見的NullPointerException空指標異常。 Error指的是一些致命的錯誤,無法通過程式程式碼手段恢復的異常,例如OutOfMemoryError記憶體溢位錯誤。 ## unchecked異常 在上圖中除了RuntimeException、Error及其子類都是屬於unchecked的異常型別外,其他的都是受編譯器checked檢查的異常。 unchecked不受編譯器檢查的異常, 是因為這些錯誤在程式執行過程中是可以通過程式設計手段去控制住的, 例如常見的NullPointerException空指標異常和IndexOutOfBoundsException陣列下標越界的異常,這些都可以事先使用if (xx != null) 以及 if (xxx.size() > i)來控制, 或者就是完全無法通過程式手段控制, 例如OutOfMemoryError記憶體溢位異常和StackOverflowError棧溢位異常,這種Error因為無法通過程式碼層面if就能避免的,所以也屬於unchecked。 ## checked異常 checked在編譯過程中受到編譯器的檢查,如果程式沒有對該異常做catch處理或者向上一層丟擲的話,程式將無法編譯通過, 常見的checked異常有FileNotFoundException檔案不存在異常等,因為這種異常在編寫階段就可以預見,例如這個檔案極有可能是不存在的,所以這種異常必須要丟擲並要求程式作出處理。 ## 總結 Throwable任何異常/錯誤的祖先類,屬於checked異常。 Exception異常,可以從異常中恢復執行的異常,屬於checked異常。 RuntimeException異常,預料之外的異常例如空指標、陣列越界,屬於unchecked異常。 ...Exception除了RuntimeException及其子類是unchecked異常,其他的Exception類都是checked異常。 Error錯誤,致命問題,無法從錯誤中恢復, 也屬於unchecked異常。 在開發過程中,如果一些可以預料的到的錯誤丟擲異常時,儘量丟擲checked異常,例如那個檔案、某個資料一定可能會不存在的情況下,就要提示該方法的呼叫者,需要對這種情況進行處理, 如果是一些預料之外的異常,則可以使用RuntimeException,例如某個值規定一定是必須不為空,但是程式判斷時為空了,則要進行RuntimeException的丟擲。 ## 面試題 ### 什麼是checked/unchecked/runtime exception? * checked exception指的是除了Error、Runtime Exception及其子類之外的所有異常, * unchecked exception指的是Error、Runtime Exception及其子類的異常, * runtime exception屬於unchecked異常。 ### try/catch/finally的執行順序 ![](https://img2020.cnblogs.com/blog/908629/202101/908629-20210104164638654-503154770.png) * try用於包含執行時的程式碼塊,第一步執行, * catch用於捕獲程式碼執行時可能發生的異常,第二步執行 當代碼塊執行到某一步發生錯誤時,後面的程式碼將不會進行執行, 而是跳轉到catch的程式碼塊中,catch順序由上而下,以第一個可以捕獲到當前異常的catch進行執行其中的內容, * finally是程式不管有沒有發生異常,這裡的程式碼最終一定會執行,所以是第三步執行。 ### 在finally中return資料會怎麼樣 ![](https://img2020.cnblogs.com/blog/908629/202101/908629-20210104164650384-1897597913.png) 由於finally在不管什麼情況下都會執行,所以finally中的return或覆蓋掉其他地方的return,最終以finally返回的為主,圖中最終返回結果是2。 ### throw和throws的區別 ![](https://img2020.cnblogs.com/blog/908629/202101/908629-20210104164702767-182782100.png) * throw是用於在程式執行過程中,如果碰到了覺得不正確的值或者結果,可以通過throw new XXX()來丟擲一個異常,終止當前程式的繼續執行。 * throws是用於在方法簽名上指出該方法將丟擲什麼異常,告訴呼叫者,呼叫此方法可能會產生的異常,讓呼叫者做相應的處理。 ### final、finally、finalize的區別 * final用於修飾類、方法、變數,在類上該類不可被繼承,在方法上,該方法不可被重寫,在變數上,該變數引用不可被更改。 * finally用於在try語句中,意味著finally包含的程式碼必須執行,不管有沒有異常。 * finalize是所有物件的一個方法,在該物件被回收前,將會被垃圾回收器呼叫,但是隻會呼叫一次,一般可以在該方法中挽救當前將被回收的物件,例如使用一個變數引用當前物件,但是這種方式不可取,因為垃圾回收器不會保證該方法被執行完畢,可能正在賦值的過程中該物件就被回收了, 這個方法類似C++的解構函式,但是不穩定,官方也不推薦使用,只是因為歷史原因,為了讓C++程式設計師更適應Java作出的一個妥協。 ## 結語 歡迎關注微信公眾號『碼仔zonE』,專注於分享Java、雲端計算相關內容,包括SpringBoot、SpringCloud、微服務、Docker、Kubernetes、Python等領域相關技術乾貨,期待與您相遇! ![](https://img2020.cnblogs.com/blog/908629/202008/908629-20200819141402537-1758432