在写Java程序的时候,当一个类找不到的时候,JVM有时候会抛出ClassNotFoundException异常,而有时候又会抛出NoClassDefFoundError。这两个异常有什么不同的地方呢?

2.1 ClassNotFoundException

  1. ClassNotFoundException是一个运行时异常。从类继承层次上来看,ClassNotFoundException是从Exception继承的,所以ClassNotFoundException是一个检查异常。
    image.png
  2. 当应用程序运行的过程中尝试使用类加载器去加载Class文件的时候,如果没有在classpath中查找到指定的类,就会抛出ClassNotFoundException。
  3. 使用Class.forName()或者ClassLoader.loadClass以及使用ClassLoader.findSystemClass()在运行时加载类时可能会抛出此异常。

2.2 NoClassDefFoundError

  1. NoClassDefFoundError异常,看命名后缀是一个Error。从类继承层次上看,NoClassDefFoundError是从Error继承的。
    image.png
  2. 当JVM在加载一个类的时候,如果这个类在编译时是可用的,但是在运行时找不到这个类的定义的时候,JVM就会抛出一个NoClassDefFoundError错误。
  3. Error并不需要应用程序去关心catch的问题。
重现

先创建一个TempClass.java,编译

public class TempClass {
}

public class MainClass {
    public static void main(String[] args) {
        TempClass t = new 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

Q.E.D.

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议