原创

NoClassDefFoundError 和 ClassNotFoundException 有什么区别?

文末领取计算机必读书籍。

平时咱们在写java代码的时候,经常会遇到2个异常:ClassNotFoundException 和 NoClassDefFoundError,从字面上看好像,好像都是找不到类的时候弹出的异常,但是jvm为什么用2个异常来表示呢?他们之间到底有什么区别?

1、ClassNotFoundException 异常

看一下类图,ClassNotFoundException 这个异常继承了Exception类,Exception是一个受检查的异常,当Exception类型的异常发生的时候,其实是允许我们通过 try catch 捕获,可以做一些恢复的措施,从而可以让程序继续运行。

file

当java程序运行的过程中,尝试用类加载器去加载一个类的时候,如果在classpath范围内没有找到指定的类,就会弹出这个异常。

通常我们使用下面3种方法通过类名加载指定的类时,如果找不到指定的类,就会报 ClassNotFoundException 异常

  • Class.forName(“完整类名”)
  • ClassLoader.loadClass(“完整类名”)
  • ClassLoader.findSystemClass(“完整类名”)

jdbc大家都用过吧,比如我们需要使用mysql,但是我们的classpath中并没有mysql驱动jar包,此时就会报错,如下:

public class C2 {
    public static void main(String[] args) {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            System.out.println("出错了!");
            e.printStackTrace();
        }
    }
}

运行输出,此时出现了ClassNotFoundException异常

java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
    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 C2.main(C2.java:4)

2、NoClassDefFoundError 异常

看一下后缀,是Error类型的异常,Error类型是程序无法处理的错误,表示运行应用程序中较严重问题,通常发生这种错误的时候,jvm会选择退出,也就是程序直接就挂掉了。

file

当jvm在编译的时候这个类是存在的,但是运行的时候找不到这个类了,就会报 NoClassDefFoundError 错误。

比如我们来2个类,Demo1和Demo2

file

public class Demo1 {
}

Demo2 new一个Demo1

public class Demo2 {
    public static void main(String[] args) {
        Demo1 demo1 = new Demo1();
        System.out.println(demo1);
    }
}

下面使用javac编译Demo2

file

此时新生成了2个class文件

file

此时运行Demo2,正常

file

然后我们把Demo1.class删掉,然后在运行java Demo2试试

file

NoClassDefFoundError 异常出现了。。。

file

3、排错思路

当出现这2种异常的时候,可以通过下面代码将classpath的路径打印出来,然后排查一下这些路径包含的文件中是否有指定的类

System.getProperty("java.class.path")

4、对比一下区别

ClassNotFoundException NoClassDefFoundError
从java.lang.Exception继承,是一个Exception类型 从java.lang.Error继承,是一个Error类型
当动态加载Class的时候找不到类会抛出该异常 当编译成功以后执行过程中Class找不到导致抛出该错误
一般在执行Class.forName()、ClassLoader.loadClass()或ClassLoader.findSystemClass()的时候抛出 由JVM的运行时系统抛出
这种异常可以进行补救 无法补救

5、计算机必读书籍

计算机必读电子书,进行了详细的分类,自己整理的,绝不是在网上那种打包下载的,而是自己需要学到某个方向的时候去网上挨个找的,最后汇总而成,这部分我是会不断把它完善的,当成自己的小电子书库,不多,但贵在精,获取方式,扫码发送:计算机

file

正文到此结束
本文目录