1. 程式人生 > >聊聊面試-NoClassDefFoundError 和 ClassNotFoundException 區別

聊聊面試-NoClassDefFoundError 和 ClassNotFoundException 區別

(上圖是聖卡塔利娜島,美國南加州的一個小島,也是 mac OS 10.15 版本的官方預設桌布)
___

概述

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() 方法動態的載入類資訊,但是這個類在類路徑中並沒有被找到,那麼就會在執行時丟擲 ClassNotFoundException

以上是大致的 NoClassDefFoundError 和 ClassNotFoundException 的區別,那麼延伸一下可以探討 Java 型別體系中的 Error 和 Exception
___

Error 和 Exception 的區別

Error 和 Exception 都是繼承 Throwable 類,它們體現 Java 設計者在對異常的不同情況所進行的分類處理,在 Java 中只有 Throwable 類的例項才能被 try/catch 捕獲或者宣告丟擲。

Error 在大多數情況下代表程式出現了致命並且不可恢復的錯誤,它們大多都是不可預測的錯誤,不需要也不能捕獲和丟擲,例如常見的 OutOfMemeryError,StackOverFlowError,還有本文提到的 NoClassDefFoundError,他們都是 Error 的子類

Exception 屬於程式錯誤,大多是人為編碼所導致的,它們大多都可以預測,也可以通過程式處理讓程式正常流程,所以是需要進行捕獲(try/catch)或者宣告丟擲(throw)的,Exception 還分兩種情況,可檢查異常 checked exception(編譯期異常),非檢查異常 unchecked exception(執行期異常)

可檢查異常是編譯期必須要顯示處理的異常,編譯器會強制要求處理這種的異常,不然編譯就不會通過,非檢查異常是程式在執行時出現的異常,大多是程式設計師處理不到導致的程式問題,例如常見的 NullPointerException,ArrayIndexOutOfBoundsException,本文標題的 ClassNotFoundException 就是屬於編譯期異常,在使用 Class.forName 需要強制處理

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


使用異常的注意事項

平時在操作異常的時候有什麼需要注意的嗎?我們先看一段簡單的程式碼示例

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 !

相關推薦

聊聊面試-NoClassDefFoundError ClassNotFoundException 區別

(上圖是聖卡塔利娜島,美國南加州的一個小島,也是 mac OS 10.15 版本的官方預設桌布) ___ 概述 Hello,大家好,我們又來講面試中的基礎題了,今天這是一道很經典又很猥瑣的題 說猥瑣是因為這兩個異常名字比較近似,但事實上他們完全不同,導致很多同學會經常容易把它們搞混 說經典是因為由這道題可

NoClassDefFoundError ClassNotFoundException 有什麼區別

ClassNotFoundException NoClassDefFoundError 從java.lang.Exception繼承,是一個Exception型別 從java.lang.Error

聊聊面試-intInteger的區別

最近面試了很多候選人,發現很多人都不太重視基礎,甚至連工作十幾年,專案經驗十幾頁的老程式設計師,框架學了一大堆,但是很多 Java 相關的基礎知識卻很多都答不上來。還有很多人會回答,只知道要用,但是從來不會去看看它具體是怎麼實現的。 我們都知道作為合格的程式設計師,基本功不紮實會導致你的程式出現許多你難以

NoClassDefFoundErrorClassNotFoundException的不同

如果JVM或者ClassLoader在載入類時找不到對應的類,就會引發NoClassDefFoundError和ClassNotFoundException,這兩種錯誤都非常嚴重。由於不同的ClassLoader會從不同的地方載入類,有時是錯誤的CLASSPATH引發這類錯誤

JAVA類的靜態載入動態載入以及NoClassDefFoundErrorClassNotFoundException

我們都知道JAVA初始化一個類的時候可以用new 操作符來初始化,也可通過Class.forName的方式來得到一個Class型別的例項,然後通過這個Class型別的例項的newInstance來初始化.我們把前者叫做JAVA的靜態載入,把後者叫做動態載入.後者在很多框架中

java.lang.NoClassDefFoundErrorjava.lang.ClassNotFoundException

NoClassDefFoundError錯誤發生的原因 NoClassDefFoundError錯誤的發生,是因為Java虛擬機器在編譯時能找到合適的類,而在執行時不能找到合適的類導致的錯誤。例如在執行時我們想呼叫某個類的方法或者訪問這個類的靜態成員的時候,發現這個類不可用,此時Java虛擬機器

Python面試之 is == 的區別

面試實習生的時候,當問到 is 和 == 的區別時,很多同學都答不上來,搞不清兩者什麼時候返回一致,什麼時候返回不一致。本文我們來看一下這兩者的區別。 我們先來看幾個例子: 上面的輸出結果中為什麼有的 is 和 == 的結果相同,有的不相同呢?我們來看下官方文件中對於 is 和

面試-堆棧的區別

我先自己總結一下: 堆的優點是:執行時動態分配記憶體大小,資料的生存期也不是固定的,java垃圾回收器會自動回收不用的資料,缺點是:由於是執行時動態分配記憶體,所以存取速度較慢。堆用來存放由new建立的物件和陣列。 棧的優點是:存取速度較快,棧資料可以共享,缺點是:棧中的資

面試問題mybatis #$的區別

這個問題面試時被問到好幾次,也是經常被問的一個問題 MyBatis中#和$的區別 1. #將傳入的資料都當成一個字串,會對自動傳入的資料加一個雙引號。如:order by #user_id#,如

java面試整理(四)—— HashMap、LinkedHashMap、TreeMap、Hashtable、HashSetConcurrentHashMap區別

注:本篇博文大部分借鑑與該篇博文系列 知識點總結 HashMap HashMap是基於雜湊表的Map介面的非同步實現, 允許使用null值和null鍵(HashMap最多隻允許一條記錄的鍵為null,允許多條記錄的值為null。)。此類不保證對映的順

【Java基本功】聊聊抽象類介面的區別

1 抽象類一般會實現一部分操作,並且留一些抽象方法讓子類自己實現,比如Stringbuffer和Stringbuilder的父類abstractStringbuilder。 2 介面一般指一種規定,比如一個map介面中,可能需要實現增刪改查等功能,如果你想實現一個具體map,這些方法就必須按照規

【Java基本功】聊聊抽象類接口的區別

uil 可能 extends system alt public java 如果 private 1 抽象類一般會實現一部分操作,並且留一些抽象方法讓子類自己實現,比如Stringbuffer和Stringbuilder的父類abstractStringbuilder。

sessioncookie 區別(面試)

session原理: 1、session是儲存在伺服器端,理論上是沒有是沒有限制,只要你的記憶體夠大 2、瀏覽器第一次訪問伺服器時會建立一個session物件並返回一個JSESSIONID=ID的值,    建立一個Cookie物件key為JSSIONID,value為I

mybatis中的#$的區別? 面試經常問到!!

1. #將傳入的資料都當成一個字串,會對自動傳入的資料加一個雙引號。如:order by #user_id#,如果傳入的值是111,那麼解析成sql時的值為order by "111", 如果傳入的值是id,則解析成的sql為order by "id".    2. $將傳入的資料直接顯示生成在sql中。如

面試】ForwordSendRedirect區別

 Forword:僅是容器中控制權的轉向,在客戶端瀏覽器位址列中不會顯示出轉向後的地址; SendRedirect:則是完全的跳轉,瀏覽器將會得到跳轉的地址,並重新發送請求連結。這樣,從瀏覽器的位址列

[面試] 程序執行緒的區別(面試題)

程序和執行緒都是由作業系統所體現的程式執行的基本單元,系統利用該基本單元實現系統對應用的併發性。程序和執行緒的區別在於: 簡而言之,一個程式至少有一個程序,一個程序至少有一個執行緒. 執行緒的劃分尺度小於程序,使得多執行緒程式的併發性高。 另外,程序在執行過程中擁有

JAVA面試要點003_Mybatis中#$的區別

#的作用: userMapper.xml 注意這裡,寫sql語句,咱們可以使用xml配置的方式,也可以使用註解的方式. E:\workspace\day76_mybatis01\src\com\credream\test2\userMapper.xml <?xml v

面試官:你說說ReentrantLockSynchronized區別

大家好!又和大家見面了。為了避免面試尷尬,今天同比較通俗語言和大家聊下ReentrantLock和Synchronized區別!   使用方式 Synchronized可以修飾例項方法,靜態方法,程式碼塊。自動釋放鎖。 ReentrantLock一般需要try catch finally語句,在t

GETPOST區別總結

get 、post 、區別一、GET和POST區別的普遍看法:HTTP 定義了與服務器交互的不同方法,最常用的有4種,Get、Post、Put、Delete,如果我換一下順序就好記了,Put(增),Delete(刪),Post(改),Get(查),即增刪改查,下面簡單敘述一下:1)Get, 它用於獲取信息,註

JS中const、varlet區別

方法 pre 命令 con 使用 它的 comm 作用 影響 在JavaScript中有三種聲明變量的方式:var、let、const。 1.const 聲明創建一個只讀的常量。這不意味著常量指向的值不可變,而是變量標識符的值只能賦值一次,必須初始化。 const b