Exception和Error有什麼區別?

典型的回答是這樣的:java

    Exception 和 Error都繼承了Throwable類,在java中只有Throwable類型的實例才能夠被拋出(Throw)或者捕捉(catch),它是異常處理機制的基本組成類型。面試

   Exception是程序正常運行中,能夠預料的意外狀況,可能而且應該被捕獲,進行相應的處理。編程

      Error指在正常狀況下,不大可能出現的狀況,絕大部門的Error都會致使程序處於非正常的,不可恢復狀態。既然是非正常狀況,因此不便於也不須要捕獲。好比常見的OutOfMemoryError之類,都是Error的子類。
函數

   Exception類又分爲可檢查異常(checked)和不檢查異常(unchecked),可檢查異常在源碼裏必須顯示的進行捕獲處理,這是編譯期檢查的一部分。性能

    不檢查異常就是所謂的運行時異常,相似NullPointerException,ArrayIndexOutOfBoundsException之類,一般是能夠編碼避免的邏輯錯誤。優化

考點分析:編碼

  分析Exception 和 Error的區別,是從概念角度考察了Java處理機制,總的來講,還處於理解層面,面試者只要闡述清楚就好。
spa

在平常的編程中如何處理好異常呢?設計

  第一,理解Throwable,Exception,Error的設計和分類。好比,掌握應用普遍的子類,以及如何自定義異常,以下圖:code

    

有些子類須要重點理解下,好比NoClassDefFoundError 和 ClassNotFoundException有什麼區別,這也是經典的題目。

 

第二,理解Java語言中操做Throwable的元素和實踐。如try-catche-finally塊,throw,throws關鍵字等,隨着JAVA語言的發展,引入了更加便利的特性,好比try-with-resources和multiple catch。代碼以下

 

try(BufferedReader br = new BufferedReader(br)){ }catch(Exception  | IOExcetion e){ }

 

知識擴展:

  前面談了不少概念性的東西,接下來結合一些代碼用例進行分析。

try { // 業務代碼 //             Thread.sleep(1000L); } catch (Exception e) { //         }

這段代碼很短,可是已經違反了異常處理的兩個基本原則。

第一,儘可能不要捕獲相似Exception這樣的通用異常,而是應該捕獲特定異常。

Thread.sleep(1000L);這段代碼拋出的InterruptedException。
第二,不要生吞異常
生吞異常每每是基於假設這段代碼可能不會發生,或者感受忽略異常時無所謂的。來看第二段代碼,以下
try { // 業務代碼 //         } catch (IOException e) { e.printStackTrace(); }

這段代碼沒有任何問題,可是不要這麼處理。

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

 

  • try-catch代碼段會產生額外的性能開銷,會影響JVM對代碼進行優化,因此建議僅捕獲有必要的代碼,不要一個大try包住整段代碼,不要用異常控制流程代碼,很低效。
  • JAVA每實例化一個Exception,都會對當時的棧進行快照,這是一個相對比較重的操做,若是發生的很是頻繁,這個開銷可就不能被忽視了。

  • 不要推諉或者延遲處理異常,就地解決最好,並須要實實在在的進行處理,而不是隻捕捉,不動做
  • 一個函數儘管拋出了多個異常,可是隻有一個異常可被傳播到調用端,最後被拋出的異常時惟一被調用端接收的異常,其餘異常都會被吞沒掩蓋。若是調用端要知道形成失敗的最初緣由,程序中就不能掩蓋異常
相關文章
相關標籤/搜索