ClassNotFoundException 和 NoClassDefFoundError 的区别

ClassNotFoundException 和 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

总结一下区别


ClassNotFoundExceptionNoClassDefFoundError
从 java.lang.Exception 继承,是一个 Exception 类型从 java.lang.Error 继承,是一个 Error 类型
当动态加载 Class 的时候找不到类会抛出该异常当编译成功以后执行过程中 Class 找不到导致抛出该错误
一般在执行 Class.forName()、ClassLoader.loadClass() 或 ClassLoader.findSystemClass() 的时候抛出由 JVM 的运行时系统抛出
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值