NoClassDefFoundError和ClassNotFoundException之间的区别是什么?

是什么导致它们被抛出?如何解决这些问题?

在修改现有代码以包含新的jar文件时,我经常遇到这些可抛出的文件。 我已经在客户端和服务器端为一个通过webstart分发的java应用程序击中了它们。

我发现的可能原因是:

未包含在代码客户端build.xml中的包 我们正在使用的新jar缺少运行时类路径 版本与上一个jar冲突

当我今天遇到这些问题时,我采取了一种反复尝试的方法来让事情正常运行。我需要更多的清晰和理解。


当前回答

ClassNotFoundException和NoClassDefFoundError的区别

其他回答

从http://www.javaroots.com/2013/02/classnotfoundexception-vs.html:

ClassNotFoundException:类装入器在类路径中找不到所需的类时发生。因此,基本上您应该检查类路径并在类路径中添加类。

NoClassDefFoundError:这更难调试和查找原因。当在编译时存在所需的类,但在运行时类被更改或删除,或者类的静态初始化抛出的异常时,将引发此异常。这意味着要加载的类存在于类路径中,但该类所需的类之一要么被删除,要么被编译器加载失败。你应该看到依赖于这个类的类。

例子:

public class Test1
{
}


public class Test 
{
   public static void main(String[] args)
   {
        Test1 = new Test1();    
   }

}

现在,在编译完这两个类之后,如果删除Test1.class文件并运行Test类,它将抛出

Exception in thread "main" java.lang.NoClassDefFoundError: Test
    at Test1.main(Test1.java:5)
Caused by: java.lang.ClassNotFoundException: Test
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    ... 1 more

ClassNotFoundException:当应用程序试图通过类的名称装入类,但无法找到具有指定名称的类的定义时抛出。

NoClassDefFoundError:如果Java虚拟机试图装入类的定义,但找不到该类的定义时抛出。

通过名称本身,我们可以很容易地识别一个来自异常,另一个来自错误。

Exception:程序执行过程中出现异常。程序员可以通过try catch块处理这些异常。我们有两种类型的异常。在编译时抛出的已检查异常。在运行时抛出的运行时异常,这些异常通常是由于糟糕的编程而发生的。

错误:这些根本不是异常,它超出了程序员的范围。这些错误通常由JVM抛出。


图片来源

的区别:

ClassNotFoundException:

类装入器无法验证链接中的字节代码。 ClassNotFoundException是一个受控异常,当应用程序试图通过类的全限定名加载类,但在类路径上找不到类的定义时,就会发生这种异常。 当使用ClassLoader.loadClass()、class . forname()和ClassLoader.findSystemClass()在运行时提供类名,涉及显式加载类时,就会出现ClassNotFoundException。

NoClassDefFoundError:

类装入器无法解析链接中的类引用。 NoClassDefFoundError是一个从LinkageError类派生的错误,这是一个致命错误。当JVM试图使用new关键字实例化一个类或使用方法调用加载一个类时,无法找到类的定义,就会发生这种情况。 NoClassDefFoundError是由于类的方法调用或任何变量访问而隐式加载类的结果。


相似之处:

NoClassDefFoundError和ClassNotFoundException都与类在运行时不可用有关。 ClassNotFoundException和NoClassDefFoundError都与Java类路径相关。

ClassNotFoundException和NoClassDefFoundError发生在运行时没有找到特定的类时。然而,它们发生在不同的场景中。

ClassNotFoundException是一个异常,当您试图在运行时使用class . forname()或loadClass()方法加载一个类,并且在类路径中没有找到所提到的类时发生。

    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(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)
    at pack1.MainClass.main(MainClass.java:17)

NoClassDefFoundError是当特定类在编译时存在,但在运行时不存在时发生的错误。

    class A
    {
      // some code
    }
    public class B
    {
        public static void main(String[] args)
        {
            A a = new A();
        }
    }

编译上述程序时,将生成两个.class文件。一个是a类,另一个是b类。如果你删除A.class文件并运行B.class文件,Java运行时系统将抛出NoClassDefFoundError,如下所示:

    Exception in thread "main" java.lang.NoClassDefFoundError: A
    at MainClass.main(MainClass.java:10)
    Caused by: java.lang.ClassNotFoundException: A
    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)

ClassNotFoundException和NoClassDefFoundError的区别

在实践中添加一个可能的原因:

ClassNotFoundException:正如cletus所说,当接口的继承类不在类路径中时使用接口。例如,服务提供者模式(或服务定位器)试图定位一些不存在的类 NoClassDefFoundError:找到了给定的类,但没有找到给定类的依赖项

在实践中,Error可能会被无声地抛出,例如,你提交了一个计时器任务,在计时器任务中它抛出了Error,而在大多数情况下,你的程序只捕获Exception。然后Timer主循环结束,没有任何信息。与NoClassDefFoundError类似的错误是ExceptionInInitializerError,当您的静态初始化器或静态变量的初始化器抛出异常时。