Exception -- 02 -- NoClassDefFoundError和ClassNotFoundException的区别

 NoClassDefFoundError 和 ClassNotFoundException 这两个异常乍看之下,名字十分相似,但它们是两个完全不同的概念,NoClassDefFoundError 是一种 Error,是程序无法处理的系统错误,而 ClassNotFoundException 是一种 Exception,是程序可以处理的异常,现在我们来看看它们之间的具体区别


一、NoClassDefFoundError

  • 当虚拟机在加载一个类时,如果该类在编译时是可用的,但是在运行时找不到该类的定义时,则虚拟机会抛出该异常

  • 示例如下

    • NoClassDefTestA.java

      public class NoClassDefTestA {
      
          public void test() {
              System.out.println("Hello World");
          }
      }
      
    • NoClassDefTestB.java

      public class NoClassDefTestB {
      
          public static void main(String[] args) {
              NoClassDefTestA test = new NoClassDefTestA();
              test.test();
          }
      }
      
    • 如上所示,有 NoClassDefTestA 和 NoClassDefTestB 两个类,在 NoClassDefTestB 中实例化 NoClassDefTestA,并调用 NoClassDefTestA 的 test() 方法

    • 我们对这两个类进行编译,得到两个对应的 Class 文件
      在这里插入图片描述

    • 然后删除 NoClassDefTestA.class 文件
      在这里插入图片描述

    • 最后运行 NoClassDefTestB 中的 main() 方法,虚拟机会抛出 NoClassDefFoundError 异常
      在这里插入图片描述


二、ClassNotFoundException

  • 当程序使用类加载器动态加载 Class 文件时,如果没有找到指定的类,则虚拟机会抛出该异常

  • 一般在执行 Class.forName()ClassLoader.loadClassClassLoader.findSystemClass() 方法时抛出

  • 示例如下

    • ClassNotFoundTest.java

      public class ClassNotFoundTest {
      
          public static void main(String[] args) throws Exception {
              Class<?> clazz = Class.forName("com.xj.exception.ClassNotFoundTestAAA");
              System.out.println(clazz);
          }
      }
      
    • 如上所示,正确的类全限定名为 com.xj.exception.ClassNotFoundTest,此处 Class.forName() 方法中使用的是 com.xj.exception.ClassNotFoundTestAAA,因此当执行 mian() 方法时,虚拟机会抛出 ClassNotFoundException 异常
      在这里插入图片描述


三、归纳总结

  • NoClassDefFoundError

    • 当虚拟机在加载一个类时,如果该类在编译时是可用的,但是在运行时找不到该类的定义时,则虚拟机会抛出该异常

    • 可以简单地理解为 “看得见,摸不着”

  • ClassNotFoundException

    • 当程序使用类加载器动态加载 Class 文件时,如果没有找到指定的类,则虚拟机会抛出该异常

    • 可以简单地理解为 “看不见,摸不着”


四、参考资料

 

 

 

posted @ 2020-05-31 15:04  GeneXu  阅读(151)  评论(0)    收藏  举报