聊聊面試-NoClassDefFoundError 和 ClassNotFoundException 區別

file

(上圖是聖卡塔利娜島,美國南加州的一個小島,也是 mac OS 10.15 版本的官方默認壁紙)java


概述

Hello,你們好,咱們又來說面試中的基礎題了,今天這是一道很經典又很猥瑣的題 說猥瑣是由於這兩個異常名字比較近似,但事實上他們徹底不一樣,致使不少同窗會常常容易把它們搞混程序員

說經典是由於由這道題能夠引出的問題有不少,例如:面試

  1. 考察候選人對 Java 異常體系的熟悉程度
  2. 考察候選人對異常體系分類的瞭解(Error / Exception)
  3. 深刻考察對 Exception 的不一樣類型的理解
  4. 經過考察面試者如何處理異常,從而考驗面試者的編程功底

彷佛有太多問題能夠探討,先不展開了,本文主要講述區別而後會再擴展一下知識點,文章大綱以下:編程

  1. NoClassDefFoundError 和 ClassNotFoundException 區別的常見回答
  2. 那麼 Error 和 Exception 有什麼的區別 ?
  3. Exception 的異常類型有哪些?
  4. 使用異常有哪些注意事項?

NoClassDefFoundError 和 ClassNotFoundException 區別的常見回答

NoClassDefFoundError 是一種 Error,Error 在大多數狀況下表明沒法從程序中恢復的致命錯誤,產生的緣由在於 JVM 或者 ClassLoader 在運行時類加載器在 classpath 下找不到須要的類定義(編譯期是能夠正常找到的,因此和 ClassNotFoundException 不一樣的是這是一個運行期的 Error),這個時候虛擬機就會拋出 NoClassDefFoundError,一般形成該 ERROR 的緣由是打包過程當中漏掉了部分類,或者 jar 包出現損壞或篡改,對應的 Class 在 classpath 中不可用等等緣由微信

ClassNotFoundException 是屬於 Exception 的運行時異常,大可能是能夠從代碼中恢復的異常類型,致使該異常的緣由大可能是由於使用 Class.forName() 方法動態的加載類信息,可是這個類在類路徑中並無被找到,那麼就會在運行時拋出 ClassNotFoundExceptionapp

以上是大體的 NoClassDefFoundError 和 ClassNotFoundException 的區別,那麼延伸一下能夠探討 Java 類型體系中的 Error 和 Exception編碼


Error 和 Exception 的區別

Error 和 Exception 都是繼承 Throwable 類,它們體現 Java 設計者在對異常的不一樣狀況所進行的分類處理,在 Java 中只有 Throwable 類的實例才能被 try/catch 捕獲或者聲明拋出。spa

Error 在大多數狀況下表明程序出現了致命而且不可恢復的錯誤,它們大多都是不可預測的錯誤,不須要也不能捕獲和拋出,例如常見的 OutOfMemeryError,StackOverFlowError,還有本文提到的 NoClassDefFoundError,他們都是 Error 的子類設計

Exception 屬於程序錯誤,大可能是人爲編碼所致使的,它們大多均可以預測,也能夠經過程序處理讓程序正常流程,因此是須要進行捕獲(try/catch)或者聲明拋出(throw)的,Exception 還分兩種狀況,可檢查異常 checked exception(編譯期異常),非檢查異常 unchecked exception(運行期異常)日誌

可檢查異常是編譯期必需要顯示處理的異常,編譯器會強制要求處理這種的異常,否則編譯就不會經過,非檢查異常是程序在運行時出現的異常,大可能是程序員處理不到致使的程序問題,例如常見的 NullPointerException,ArrayIndexOutOfBoundsException,本文標題的 ClassNotFoundException 就是屬於編譯期異常,在使用 Class.forName 須要強制處理

一圖勝千言,爲了方便你們直觀感覺,我大概畫了一個簡單的異常體系結構圖,僅供參考:

file


使用異常的注意事項

平時在操做異常的時候有什麼須要注意的嗎?咱們先看一段簡單的代碼示例

try {
		// 業務代碼
		// something happened
		Thread.sleep(100);
} catch (Exception e) {
	
}

// 業務代碼

以上代碼犯了哪幾個明顯的錯誤?我簡單列舉一下:

  1. 捕獲異常應該使用特定的類型的 Exception
  2. 沒有對異常進行任何處理

爲何要捕獲特定類型的異常 ?主要有如下幾點 由於你的代碼會被團隊不少人閱讀,寬泛的使用 Exception 對全部異常進行處理會讓別人很差理解你代碼的異常,程序的主要目的也是要體現它的語義,例如 Thread.sleep 是明確拋出 InterruptedException,Class.forName 明確拋出 ClassNotFoundException,那麼應該針對 InterruptedException,ClassNotFoundException 這種明確的異常進行明確的處理,而不是泛泛的使用 Exception 包住全部的異常

沒有對異常進行任何處理 這個問題其實比上面更嚴重,這種行爲本質上是在掩蓋問題,不只會致使出現各類詭異的問題,並且徹底沒有線索能夠跟蹤,沒有人能夠猜想到程序是在哪裏出了問題,致使定位問題很是低效,因此若是沒有拋出異常,最起碼也要把對應的的錯誤信息 到日誌內,而不是「生吞」異常,人爲的爲診斷設置障礙


總結

咱們經過一個簡單的 NoClassDefFoundError 和 ClassNotFoundException 區別 的問題和一個簡單的異常處理程序 demo 牽引出 Java 的異常體系和不一樣的分類和平時對異常處理的注意事項

另外推薦你們在實踐中儘可能使用統一異常處理的機制,例如 Spring 提供了幾種的全局異常處理機制:

  • 實現 HandlerExceptionResolver 接口
  • 在Controller內部,用 @ExceptionHandler 註解處理異常
  • 全局 Controller 異常處理註解 @ControllerAdvice ,能夠根據類型處理特定異常

今天文章寫到這裏,但願能夠幫助你們加深對異常概念的理解,碼字不易,以爲不錯能夠點贊,轉發,你的鼓勵是個人動力 更多技術諮詢,請關注公衆號,find me ! alt 微信公衆號

相關文章
相關標籤/搜索