ClassNotFoundException和NoClassDefFoundError的區別


blog地址:https://tech101.cn/2018/06/23/ClassNotFoundException_vs_NoClassDefFoundError

  在寫Java程序的時候,當一個類找不到的時候,JVM有時候會拋出ClassNotFoundException異常,而有時候又會拋出NoClassDefFoundError。看兩個異常的字面意思,好像都是類找不到,但是JVM為什么要用兩個異常去區分類找不到的情況呢?這個兩個異常有什么不同的地方呢?

ClassNotFoundException

  ClassNotFoundException是一個檢查異常。從類繼承層次上來看,ClassNotFoundException是從Exception繼承的,所以ClassNotFoundException是一個檢查異常。

  當應用程序運行的過程中嘗試使用類加載器去加載Class文件的時候,如果沒有在classpath中查找到指定的類,就會拋出ClassNotFoundException。一般情況下,當我們使用Class.forName()或者ClassLoader.loadClass以及使用ClassLoader.findSystemClass()在運行時加載類的時候,如果類沒有被找到,那么就會導致JVM拋出ClassNotFoundException。

  最簡單的,當我們使用JDBC去連接數據庫的時候,我們一般會使用Class.forName()的方式去加載JDBC的驅動,如果我們沒有將驅動放到應用的classpath下,那么會導致運行時找不到類,所以運行Class.forName()會拋出ClassNotFoundException。

public class MainClass {
    public static void main(String[] args) {
        try {
            Class.forName("oracle.jdbc.driver.OracleDriver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

輸出:

java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at MainClass.main(MainClass.java:7)

NoClassDefFoundError

  NoClassDefFoundError異常,看命名后綴是一個Error。從類繼承層次上看,NoClassDefFoundError是從Error繼承的。和ClassNotFoundException相比,明顯的一個區別是,NoClassDefFoundError並不需要應用程序去關心catch的問題。

  當JVM在加載一個類的時候,如果這個類在編譯時是可用的,但是在運行時找不到這個類的定義的時候,JVM就會拋出一個NoClassDefFoundError錯誤。比如當我們在new一個類的實例的時候,如果在運行是類找不到,則會拋出一個NoClassDefFoundError的錯誤。

public class TempClass {
}

public class MainClass {
    public static void main(String[] args) {
        TempClass t = new TempClass();
    }
}

首先這里我們先創建一個TempClass,然后編譯以后,將TempClass生產的TempClass.class文件刪除,然后執行程序,輸出:

Exception in thread "main" java.lang.NoClassDefFoundError: TempClass
    at MainClass.main(MainClass.java:6)
Caused by: java.lang.ClassNotFoundException: TempClass
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 1 more

總結一下區別

ClassNotFoundException NoClassDefFoundError
從java.lang.Exception繼承,是一個Exception類型 從java.lang.Error繼承,是一個Error類型
當動態加載Class的時候找不到類會拋出該異常 當編譯成功以后執行過程中Class找不到導致拋出該錯誤
一般在執行Class.forName()、ClassLoader.loadClass()或ClassLoader.findSystemClass()的時候拋出 由JVM的運行時系統拋出


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM