Java異常體系概述

Java的異常體系結構

Java異常體系的根類是 Throwable, 因此當寫在java代碼中寫throw拋出異常時,後面跟的對象必然是Throwable或其子類的對象。
其中Exception異常是指一些能夠恢復的異常, 例如常見的NullPointerException空指針異常。
Error指的是一些致命的錯誤,沒法經過程序代碼手段恢復的異常,例如OutOfMemoryError內存溢出錯誤。java

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的執行順序

  • try用於包含運行時的代碼塊,第一步執行,
  • catch用於捕獲代碼運行時可能發生的異常,第二步執行
    當代碼塊執行到某一步發生錯誤時,後面的代碼將不會進行執行,
    而是跳轉到catch的代碼塊中,catch順序由上而下,以第一個能夠捕獲到當前異常的catch進行執行其中的內容,
  • finally是程序無論有沒有發生異常,這裏的代碼最終必定會執行,因此是第三步執行。

在finally中return數據會怎麼樣

因爲finally在無論什麼狀況下都會執行,因此finally中的return或覆蓋掉其餘地方的return,最終以finally返回的爲主,圖中最終返回結果是2。數組

throw和throws的區別

  • throw是用於在程序運行過程當中,若是碰到了以爲不正確的值或者結果,能夠經過throw new XXX()來拋出一個異常,終止當前程序的繼續執行。
  • throws是用於在方法簽名上指出該方法將拋出什麼異常,告訴調用者,調用此方法可能會產生的異常,讓調用者作相應的處理。

final、finally、finalize的區別

  • final用於修飾類、方法、變量,在類上該類不可被繼承,在方法上,該方法不可被重寫,在變量上,該變量引用不可被更改。
  • finally用於在try語句中,意味着finally包含的代碼必須執行,無論有沒有異常。
  • finalize是全部對象的一個方法,在該對象被回收前,將會被垃圾回收器調用,可是隻會調用一次,通常能夠在該方法中挽救當前將被回收的對象,例如使用一個變量引用當前對象,可是這種方式不可取,由於垃圾回收器不會保證該方法被執行完畢,可能正在賦值的過程當中該對象就被回收了,
    這個方法相似C++的析構函數,可是不穩定,官方也不推薦使用,只是由於歷史緣由,爲了讓C++程序員更適應Java做出的一個妥協。

結語

歡迎關注微信公衆號『碼仔zonE』,專一於分享Java、雲計算相關內容,包括SpringBoot、SpringCloud、微服務、Docker、Kubernetes、Python等領域相關技術乾貨,期待與您相遇!
微信

相關文章
相關標籤/搜索