二、ClassNotFoundException vs NoClassDefFoundError

相信java的開發(fā)者經(jīng)常會遇到這兩個異常,乍一看兩個就長得很像,有時候真的是老虎,老鼠傻傻讓人分不清楚。

1. 兩者對比

類別 ClassNotFoundException NoClassDefFoundError
含義 找不到類定義 找不到類定義
繼承 extends ReflectiveOperationException extends LinkageError
類型 反射操作引起的一種異常 一種鏈接錯誤
捕獲 catch Exception/Throwable catch Error/Throwable
原因 通過反射根據(jù)指定類名無法找到類時,會引起該異常 編譯時有類定義,運行時丟失類定義會引起該異常。運行時類定義丟失往往有兩種情況:1)類不在ClassPath內(nèi),導(dǎo)致無法加載類定義,即由ClassNotFoundException引起。2)類初始化失敗,導(dǎo)致加載不到類定義,此時會伴隨著一個初始化異常(ExceptionInInitializerError)。

2. 兩者關(guān)系

NoClassDefFoundError可由ClassNotFoundException引起。

3. 兩者定義

NoClassDefFoundError doc

當(dāng)JVM或類加載器去加載一個類定義(無論是通過普通的方法調(diào)用,還是用new語句去創(chuàng)建該類的實例所觸發(fā)的類加載),如果該類的定義丟失,那么就會拋出NoClassDefFoundError.
被加載的類定義當(dāng)前執(zhí)行類編譯時是存在的,但是再也找不到了。

ClassNotFound doc

當(dāng)應(yīng)用使用類的字符串名,通過以下方式嘗試去加載類,但是根據(jù)指定的名稱無法找到類定義時會拋出ClassNotFoundException:
1)Class.forName()
2)ClassLoader.findSystemClass()
3)ClassLoader.loadClass()

4. 實例

4.1 ClassNotFoundExcption
package qiweiTest;

public class ClassNotFoundExcptionTest {
    public static void main(String[] args) {
        Class.forName("anyNoexistClassName"); // 任何一個不存在的className
    }
}
4.2 NoClassDefError
4.2.1 類不在ClassPath引發(fā)的異常
package qiweiTest;

public class NoClassDefErrorTest {
     // 運行時,刪除ClassPath中的ClassNotFoundExceptionTest.class
    public static void main(String[] args) {
        ClassNotFoundExceptionTest.class.getClass();
    }
}

輸出:

Exception in thread "main" java.lang.NoClassDefFoundError: qiweiTest/ClassNotFoundExceptionTest
    at qiweiTest.NoClassDefErrorTest.main(NoClassDefErrorTest.java:9)
Caused by: java.lang.ClassNotFoundException: qiweiTest.ClassNotFoundExceptionTest
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    ... 1 more
4.2.2 類初始化失敗引發(fā)的異常
package qiweiTest;

public class NoClassDefErrorTest2 {
        public static void main(String[] args) {
        int tmp;
        try {
            tmp = InterClass.a;
        } catch (Throwable e) {
            // 異常類型:ExceptionInInitializerError
            e.printStackTrace();
        }
        try {
            tmp = InterClass.a;
        } catch (Throwable e) {
            // 異常類型:NoClassDefFoundError
            e.printStackTrace();
        }
    }

    static class InterClass {
        static int a;
        static {
            a = 1 / 0;
        }
    }

輸出:

java.lang.ExceptionInInitializerError
    at qiweiTest.NoClassDefErrorTest2.main(NoClassDefErrorTest2.java:8)
Caused by: java.lang.ArithmeticException: / by zero
    at qiweiTest.NoClassDefErrorTest2$InterClass.<clinit>(NoClassDefErrorTest2.java:22)
    ... 1 more
java.lang.NoClassDefFoundError: Could not initialize class qiweiTest.NoClassDefErrorTest2$InterClass
    at qiweiTest.NoClassDefErrorTest2.main(NoClassDefErrorTest2.java:13)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 類加載器是 Java 語言的一個創(chuàng)新,也是 Java 語言流行的重要原因之一。它使得 Java 類可以被動態(tài)加載到...
    CHSmile閱讀 1,672評論 0 12
  • ClassLoader翻譯過來就是類加載器,普通的java開發(fā)者其實用到的不多,但對于某些框架開發(fā)者來說卻非常常見...
    時待吾閱讀 1,167評論 0 1
  • 1. 概述 類加載器實際定義了類的namespace。 2.類加載方式之當(dāng)前類加載器和指定類加載器 類的加載只有兩...
    YDDMAX_Y閱讀 621評論 0 1
  • 一、什么是ClassLoader? 大家都知道,當(dāng)我們寫好一個Java程序之后,不是管是CS還是BS應(yīng)用,都是由若...
    全能程序猿閱讀 36,360評論 1 6
  • 一、什么是ClassLoader? 大家都知道,當(dāng)我們寫好一個Java程序之后,不是管是CS還是BS應(yīng)用,都是由若...
    Q南南南Q閱讀 3,013評論 0 8

友情鏈接更多精彩內(nèi)容