ClassNotFoundException 和 NoClassDefFoundError 有什么区别?

简介: ClassNotFoundException 是个 Exception,是使用类似 Class.forName() 等方法动态加载类时,由于找不到对应的类而发生的 checked exception。

ClassNotFoundException 是个 Exception,是使用类似 Class.forName() 等方法动态加载类时,由于找不到对应的类而发生的 checked exception

NoClassDefFoundError 是个 Error,是指一个 class 在编译时存在,在运行时找不到了 class 文件了。

一、ClassNotFoundException

典型触发场景,调用以下方法时加载失败:

  1. Class.forName(),
  2. ClassLoader.loadClass()
  3. ClassLoader.findSystemClass()
  4. 通过反射机制初始化类

如加载数据库驱动时:

public class ExceptionTest {
   
   

    public static void main(String[] args)throws Exception {
   
   
        Class.forName("oracle.jdbc.driver.OracleDriver");
    }
}

二、NoClassDefFoundError

典型触发场景如下:

1.编译时存在某个类,但是运行时却找不到

public class A {
   
   

    public void hello(){
   
   
        System.out.println("hello, world.");
    }
}

 class B {
   
   

     public static void main(String[] args) {
   
   
         A a = new A();
     }

}

上面的 Java 类编译后会生成两个类文件,一个 A.class,一个B.class。

现在我在编译后,删掉了 A 的 class 文件,然后直接执行 B 的 main 方法,就会抛出 NoClassDefFoundError 错误,因为当执行到 A a=new A() 这一步的时候,JVM认为这个类肯定在当前的 classpath 里面的,要不然编译都不会通过。

既然它存在,那么在 JVM 里面一定能找到,如果不能找到,那就说明出大事了,因为编译和运行不一致,所以直接抛出这个 ERROR,代表问题很严重。

2.一个类没有初始化成功,其他类调用这个类,导致执行失败

初始化失败的类:

public class  InitFail {
   
   

    static double divideZero = 1/0;//故意使得类初始化失败.

    public static void print(){
   
   
        System.out.println("123");
    }
}

调用如下:

public static void main(String[] args) {
   
   
        try {
   
   
            double divideZero = InitFail.divideZero;
        }catch (Throwable e){
   
   
            //此处,必须用Throwable,用Exception会直接退出.
            System.out.println(e);
        }
        //继续使用.
        InitFail.print();
    }

这种情况比较特殊,并不是因为编译时和运行时环境不一致导致的,而是对于一个类如果初始化失败后,还继续使用。

JVM 会认为是不正常的,由于它第一次调用已经失败,JVM 就会假设后面继续调用肯定仍然会失败,所以直接抛 ERROR 给客户端。

三、总结

用一个表格总结一下:

相关文章
|
Java
Java - nested exception is java.lang.StackOverflowError
Java - nested exception is java.lang.StackOverflowError
339 0
|
1月前
|
IDE 前端开发 Java
怎样避免 Java 中的 NoSuchFieldError 异常
在Java中避免NoSuchFieldError异常的关键在于确保类路径下没有不同版本的类文件冲突,避免反射时使用不存在的字段,以及确保所有依赖库版本兼容。编译和运行时使用的类版本应保持一致。
78 7
|
6月前
|
Java API 数据安全/隐私保护
如何在Java中处理InvalidKeyException异常?
如何在Java中处理InvalidKeyException异常?
|
5月前
|
Java 编译器
Java运行时异常和非运行时异常
Java运行时异常和非运行时异常
|
5月前
|
Java UED
Java中如何优雅地处理FileNotFoundException异常?
Java中如何优雅地处理FileNotFoundException异常?
|
6月前
|
安全 Java 开发者
如何解决Java中的ClassCastException异常
如何解决Java中的ClassCastException异常
|
Java
Java 自定义异常(Exception)
Java 自定义异常(Exception)
73 0
|
Java 数据库连接 数据库
50. ClassNotFoundException 和 NoClassDefFoundError 有什么区别
50. ClassNotFoundException 和 NoClassDefFoundError 有什么区别
98 0
50. ClassNotFoundException 和 NoClassDefFoundError 有什么区别
|
Java 数据库连接 数据库
NoClassDefFoundError 和 ClassNotFoundException 有什么区别
NoClassDefFoundError 和 ClassNotFoundException 有什么区别
115 1