02、談一談Java中的Error和Exception

Error和Exception的聯繫

繼承結構:Error和Exception都是繼承於Throwable,RuntimeException繼承自Exception。

Error和RuntimeException及其子類稱爲未檢查異常(Unchecked exception),其它異常成爲受檢查異常(Checked Exception)。

 

Error和Exception的區別

Error類一般是指與虛擬機相關的問題,如系統崩潰,虛擬機錯誤,內存空間不足,方法調用棧溢出等。如java.lang.StackOverFlowError和Java.lang.OutOfMemoryError。對於這類錯誤的導致的應用程序中斷,僅靠程序本身無法恢復和預防,遇到這樣的錯誤,建議讓程序終止。

Exception類表示程序可以處理的異常,可以捕獲且可能恢復。遇到這類異常,應該儘可能處理異常,使程序恢復運行,而不應該隨意終止異常。

 

未檢查異常(運行時異常)和受檢查的異常

Exception又分爲運行時異常(Runtime Exception)和受檢查的異常(Checked Exception )

未檢查異常(RuntimeException):其特點是Java編譯器不去檢查它,也就是說,當程序中可能出現這類異常時,即使沒有用try……catch捕獲,也沒有用throws拋出,還是會編譯通過。如除數爲零ArithmeticException、錯誤的類型轉換、數組越界訪問和試圖訪問空指針等。處理RuntimeException的原則是:如果出現RuntimeException,那麼一定是程序員的錯誤。

受檢查的異常(IOException等):這類異常如果沒有try……catch也沒有throws拋出,編譯是通不過的。這類異常一般是外部錯誤,例如文件找不到、試圖從文件尾後讀取數據等,這並不是程序本身的錯誤,而是在應用環境中出現的外部錯誤。

 

throw 和 throws兩個關鍵字有什麼不同

throw 是用來拋出任意異常的,你可以拋出任意 Throwable,包括自定義的異常類對象;throws總是出現在一個函數頭中,用來標明該成員函數可能拋出的各種異常。如果方法拋出了異常,那麼調用這個方法的時候就需要處理這個異常。

 

try-catch-finally-return執行順序

1、不管是否有異常產生,finally塊中代碼都會執行;

2、當try和catch中有return語句時,finally塊仍然會執行;

3、finally是在return後面的表達式運算後執行的,所以函數返回值是在finally執行前確定的。無論finally中的代碼怎麼樣,返回的值都不會改變,仍然是之前return語句中保存的值;

4、finally中最好不要包含return,否則程序會提前退出,返回值不是try或catch中保存的返回值。

 

NoClassDefFoundError 和 ClassNotFoundException 有什麼區別?

 

java.lang.NoClassDefFoundError:

類加載器試圖加載類的定義,但是找不到這個類的定義,而實際上這個類文件是存在的。

 

java.lang.ClassNotFoundException:

從規範說明看, java.lang.ClassNotFoundException 異常拋出的根本原因是類文件找不到。

 

碰到最多的是 java.lang.ClassNotFoundException。從異常的名字看,很容易理解這個異常產生的原因是缺少了 .class 文件,比如少引了某個 jar,解決方法通常需要檢查一下 classpath 下能不能找到包含缺失 .class 文件的 jar。

 

java.lang.NoClassDefFoundError 異常,這個異常的來源根本不是因爲缺少 .class 文件。而碰到這個異常的解決辦法,一般需要檢查這個類定義中的初始化部分(如類屬性定義、static 塊等)的代碼是否有拋異常的可能,如果是 static 塊,可以考慮在其中將異常捕獲並打印堆棧等,或者直接在對類進行初始化調用(如 new Foobar())時作 try  catch。

 

我們從性能角度來審視一下 Java 的異常處理機制,有兩個可能會相對昂貴的地方

1、try-catch 代碼段會產生額外的性能開銷,或者換個角度說,它往往會影響 JVM 對代碼進行優化,所以建議僅捕獲有必要的代碼段,儘量不要一個大的 try 包住整段的代碼;

與此同時,利用異常控制代碼流程,也不是一個好主意,遠比我們通常意義上的條件語句(if/else、switch)要低效。

 

2、Java 每實例化一個 Exception,都會對當時的棧進進行快照,這是一個相對比較重的操作。如果發生的非常頻繁,這個開銷可就不能被忽略了。

 

發佈了96 篇原創文章 · 獲贊 19 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章