從本質上來講,java異常是一個java對象(繼承Object),和一般的java對象一樣,封裝了一些成員變量和操作,我們可以向操作一般java對象那樣去操作java異常對象(我還特地去試了試可不可以使用throw關鍵字操作一般的java對象,發現編譯錯誤,證明它僅僅是操作異常類的語法)
從代表的含義上來說:java異常是一種錯誤情況,是程序不希望出現的現象,但是由於程序本身的設計邏輯和運行的環境等因素,出現異常的情況不可避免,java虛擬機針對不同的異常情況定義了很多異常類,當jvm運行程序發現對應的異常時,將會向外面拋出異常
java提供了拋出異常捕獲異常的邏輯用於處理異常,當程序拋出異常時,如果不存在捕獲異常邏輯,正在執行的方法將停止執行,並將該異常向外拋出,調用該方法的程序進行同樣的處理,如果也沒有進行捕獲,則將一層一層的向外拋出,直到到達當前線程處時將會終止線程的執行。
處理異常的邏輯是使用try catch finally語句塊,這個語句塊允許通過對可捕獲的異常進行異常處理,類似於一個條件判斷一樣,當出現異常時我們應該干什麼,try catch finally語句塊的具體語法規則見其他資料,這裡說一下一些容易被忽略的地方:
1)在try塊中和finally塊中都存在對同一變量的操作,同時在try塊中會返回該變量,具體如下:
public static int test(){ int i=10; try{ return i; }finally{ i= i+2; } }
則調用該方法將返回一個什麼值?按照道理說,finally最後將被執行,應該返回12,實際上返回的是10,這是因為在執行到return語句時會創建一個臨時變量用於存放返回值i,執行完finally後再返回臨時變量的值,對於基本數據類型因為是值傳遞,所有finally操作的是方法中的變量而沒有操作臨時變量的數據,因此不會生效,如果是對象,因為臨時變量存放的是對象的變量,因次在finally中的操作將會生效,這裡有些問題就是包裝類和String類和基本類型一樣不會生效,不知道什麼原因。
2)如果是自定義的java類型,則finally中的修改將會生效,具體如下:
public static data test(){ data d = new data(); try{ return d; }finally{ d.inte=15; } } private static class data{ public int inte=10; }
所有的java異常類均拓展於Throwable類,而Throwable類有兩個子類分別是Error和Exception類,Error類表示由於虛擬機自身原因導致的錯誤,如虛擬機內部錯誤以及內存溢出等;而Exception則是程序本身的運行情況導致的錯誤,包含程序邏輯問題以及程序IO交互問題。程序設計基本不怎麼關注Error,換句話說出現Error異常除了重啟之外基本無能為力,這個是屬於jvm本身的問題,而我們更多的關注的Exception類錯誤。
Exception類包含兩類錯誤:
1)RuntimeException(運行時異常),這個是程序設計的邏輯存在問題,說白了就是你的問題,優秀的程序員通常比較少犯這樣的錯誤,新手就不好說了,下面列舉常見的RuntimeException:盡量不要使用捕獲該異常來解決,應該從設計程序的角度來避免該異常的出現,比如調用一個可能會出現以下異常的方法時,最好是提前做檢查後再調用方法
2)IOException(IO異常):這一類異常通常是程序與資源打交道或者以接口打交道造成,程序本身並不能控制資源和接口的正確性,因此這一類異常在程序中是允許發生的,通常我們需要捕獲這一類異常來確定在發生異常的情況下應該做什麼,常見的IOException如下:
題外話:java對異常的處理說白了及時能通過程序控制的就盡量不讓它出現,不能通過程序控制的就捕獲它來處理,此外我們應該記住一些基本的異常,說不准哪天面試官就問你說說幾個你常見的異常,如果你說你沒見過異常那就搞笑了