Java理解ClassNotFoundException与NoClassDefFoundError的区别

Posted N!CE波

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java理解ClassNotFoundException与NoClassDefFoundError的区别相关的知识,希望对你有一定的参考价值。

一、概念上的认识

1)Exception与Error的区别

  1.Exception的出现不会导致程序结束,用户程序可以捕获该异常

  2.Error的出现会导致程序结束,用户程序无法捕获Error错误

2)ClassNotFoundException和NoClassDefFoundError相同点和不同点

相同点:

  都是由于在运行时,程序无法加载指定的类,也就是在通过类的全限定名称无法找到匹配的class文件

不同点:

  ClassNotFoundException一般是通过反射获取某个类时会出现,比如Class.forName("类的全限定名称")

  NoClassDefFoundError一般是通过new的方式创建某个类的时候,并且在编译期class类存在,但是运行期等到加载类的时候class不存在(比如丢了或者手动删除了)

3)都是由于类不存在导致的,为啥又要区分呢

  我觉得,是因为出现的场景不一样,ClassNotFoundException出现的场景比如反射获取某个类的时候,类不存在可能是正常的,是用户所预期的。但是NoClassDefFoundError出现的场景是new,那么类不存在肯定不是用户所预期的,是不正常的,所以用error来终止程序的运行。

 

二、模拟这两种异常的出现

注意下面所创建的类都没有指定package包名,目的方便在当前目录,使用java命令直接可以执行

1)ClassNotFoundException

1.创建ClassNotFoundExceptionTest.java测试类

/**
 * @author zhangboqing
 * @date 2019/11/27
 */
public class ClassNotFoundExceptionTest {
    public static void main(String[] args) throws ClassNotFoundException {
        Class.forName("HaHa");
    }
}

2.javac编译ClassNotFoundExceptionTest.java会生成ClassNotFoundExceptionTest.class类

javac ClassNotFoundExceptionTest.java

3.java执行ClassNotFoundExceptionTest中的main方法,就会出现ClassNotFoundException

?  Downloads java ClassNotFoundExceptionTest
Exception in thread "main" java.lang.ClassNotFoundException: HaHa
    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 ClassNotFoundExceptionTest.main(ClassNotFoundExceptionTest.java:7)

2)NoClassDefFoundError

1.创建NoClassDefFoundErrorTest的测试类和TestNoClassDefFoundErrorBean的不同类

/**
 * @author zhangboqing
 * @date 2019/11/27
 */
public class NoClassDefFoundErrorTest {
    public static void main(String[] args) throws ClassNotFoundException {
        TestNoClassDefFoundErrorBean bean = new TestNoClassDefFoundErrorBean();
        System.out.println(bean.name);
    }
}
/**
 * @author zhangboqing
 * @date 2019/11/27
 */
public class TestNoClassDefFoundErrorBean {
    public String name = "1212";
}

2.javac编译上面两个类

javac NoClassDefFoundErrorTest.java TestNoClassDefFoundErrorBean.java

3.将生成的TestNoClassDefFoundErrorBean.class删除掉

4.java执行NoClassDefFoundErrorTest中main方法,就会出现NoClassDefFoundError

?  Downloads java NoClassDefFoundErrorTest
Exception in thread "main" java.lang.NoClassDefFoundError: TestNoClassDefFoundErrorBean
    at NoClassDefFoundErrorTest.main(NoClassDefFoundErrorTest.java:7)
Caused by: java.lang.ClassNotFoundException: TestNoClassDefFoundErrorBean
    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

 

以上是关于Java理解ClassNotFoundException与NoClassDefFoundError的区别的主要内容,如果未能解决你的问题,请参考以下文章

java序列化与反序列化流的操作,打印流的输出

android 库项目中的方法引用过多 - ClassNotFoundException

深入理解Java内存模型

java内存模型深入理解java内存模型的系列好文

深入理解Java虚拟机的目录

深入理解Java虚拟机:JVM高级特性与最佳实践的内容简介