ClassNotFoundException和NoClassDefFoundError的区别

  在写Java程序的时候,常常因为类不存在或者找不到而抛出ClassNotFoundException,而有时却又会抛出NoClassDefFoundError。从字面意思上看,这两个都是类找不到,无非一个是Exception、一个是Error,那么这两个异常又有什么不同呢?
在这里插入图片描述


ClassNotFoundException

ClassNotFoundException是一个运行时异常。从类继承来看,ClassNotFoundException是从Exception继承的,所以ClassNotFoundException是一个检查异常。
在这里插入图片描述

当应用程序尝试使用其字符串名称通过其字符串名称加载类时如果未找到,将会抛出此异常。

  • Class.forName(java.lang.String)
  • ClassLoader.findSystemClass(java.lang.String)
  • ClassLoader.loadClass(java.lang.String, boolean)

作为最常见的,当我们使用JDBC连接数据库时,需要使用 Class.forName(java.lang.String)去加载数据库的驱动,如果我们没有讲驱动jar包放到应用的classpath下,则运行时会找不到此类,则Class.forName(java.lang.String)会抛出ClassNotFoundException异常。

/**
 * @Author HYL
 * @Date 2019/11/16 下午8:24
 * @Version 1.0
 **/
public class Test {

    public static void main(String[] args) {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

输出:

java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
	at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:264)
	at Test.main(Test.java:10)

NoClassDefFoundError

NoClassDefFoundError看后缀名是一个Error。Error是指在正常情况下,不大可能出现的情况。绝大多数的Error都会导致程序(比如 JVM 自身)处于非正常的、不可恢复状态。既然是非正常情况,所以不便于也不需要捕获,常见的比如 OutOfMemoryError 之类,都是 Error 的子类。
在这里插入图片描述

当JVM在加载一个类的时候,如果这个类在编译时是可用的,但是在运行时找不到这个类的定义的时候,JVM就会抛出一个NoClassDefFoundError错误。比如当我们在new一个类的实例的时候,如果在运行是类找不到,则会抛出一个NoClassDefFoundError的错误。

/**
 * @Author HYL
 * @Date 2019/11/16 下午8:24
 * @Version 1.0
 **/
public class Test {

    public static void main(String[] args) {
        Demo demo = new Demo();    
    }
}

class Demo{
    
}

编译:
在这里插入图片描述
在这里插入图片描述

可以清楚的看到,我们Test.java中写了两个类,在编译后生成类两个字节码文件,我们把Demo.class文件删掉后,看会发生什么。
在这里插入图片描述

在这里插入图片描述

Exception in thread "main" java.lang.NoClassDefFoundError: Demo
	at Test.main(Test.java:9)
Caused by: java.lang.ClassNotFoundException: Demo
	at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
	... 1 more

总结

ClassNotFoundExceptionNoClassDefFoundError
从java.lang.Exception继承,是一个Exception类型从java.lang.Error继承,是一个Error类型
Java支持使用反射方式在运行时动态加载类,例如使用Class.forName方法来动态地加载类时,可以将类名作为参数传递给上述方法从而将指定类加载到JVM内存中,如果这个类在类路径中没有被找到,那么此时就会在运行时抛出ClassNotFoundException异常如果JVM或者ClassLoader实例尝试加载(可以通过正常的方法调用,也可能是使用new来创建新的对象)类的时候却找不到类的定义。要查找的类在编译的时候是存在的,运行的时候却找不到了。这个时候就会导致NoClassDefFoundError
要确保所需的类连同它依赖的包存在于类路径中,常见问题在于类名书写错误查找那些在开发期间存在于类路径下但在运行期间却不在类路径下的类

文章为ArvinHan原创,如果文章有错的地方欢迎指正,大家互相交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值