ClassNotFoundException与NoClassDefFoundError

Dee*_*ohn 20 java exception noclassdeffounderror classnotfoundexception

我已经完成了这个线程是什么原因以及NoClassDefFoundError和ClassNotFoundException之间有什么区别? 这是一个在线程中具有max ups的ans之一: NoClassDefFoundError:"因此,当源成功编译时,似乎会发生 NoClassDefFoundError ,但是在运行时,找不到所需的类文件.这可能是在分发或生成JAR文件时可能发生的事情,其中​​并未包含所有必需的类文件."

ClassNotFoundException:对于ClassNotFoundException,它似乎可能源于尝试在运行时对类进行反射调用,但程序试图调用的类不存在.

我做了一个小实验.我创建了一个主类,类A,并尝试从中调用其他类,类B,编译成功.

然后我删除了在类A中调用的类B.我得到了 java.lang.ClassNotFoundException但是根据脚步中的答案,我应该得到NoClassDefFoundError(源代码已成功编译,但未找到运行时类文件)任何人都可以解释我在线程中对ans的解释中缺少什么?

package com.random;

public class A {

    public static void main(String[] args) {
        B b= new B();

    }

}

 package com.random;

public class B {



}
Run Code Online (Sandbox Code Playgroud)

Jea*_*ard 13

的NoClassDefFoundError

如果Java虚拟机或ClassLoader实例尝试加载类的定义(作为普通方法调用的一部分或作为使用新表达式创建新实例的一部分)并且无法找到类的定义,则抛出该异常.

搜索的类定义在编译当前正在执行的类时存在,但无法再找到该定义.


ClassNotFoundException的

当应用程序尝试使用以下方法通过其字符串名称加载类时抛出:类Class中的forName方法.类ClassLoader中的findSystemClass方法.类ClassLoader中的loadClass方法.


你必须明白,JVM无法实现class你删除的定义无法找到,因为class自己无法找到自动抛出的内容ClassNotFoundException.

这个异常发生在runtime如此,无论是否先编译,你删除了文件,因此无法找到并抛出exception.

请注意,NoClassDefFoundError并不是真正的例外,它是Error源自LinkageError而ClassNotFoundException直接获得java.lang.Exception.

要恢复,NoClassDefFoundError全局只是意味着JVM尝试访问runtime根据compiled代码存在的内容,但实际上不存在(或不在类路径中).


重现ClassNotFoundException的示例

public class ClassNotFoundExceptionExample {

    private static final String CLASS_TO_LOAD = "main.java.Utils";

    public static void main(String[] args) {
        try {
            Class loadedClass = Class.forName(CLASS_TO_LOAD);
            System.out.println("Class " + loadedClass + " found successfully!");
        }
        catch (ClassNotFoundException ex) {
            System.err.println("A ClassNotFoundException was caught: " + ex.getMessage());
            ex.printStackTrace();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

重现NoClassDefFoundError的示例

创建一个简单的类 Test

public class Test {
        public Test() {
                System.out.println("A new instance of the Test class was created!");
        }
}
Run Code Online (Sandbox Code Playgroud)

还有一堂课 NoClassDefFoundErrorExample

public class NoClassDefFoundErrorExample {
        private static Test test = new Test();

        public static void main(String[] args) {
                System.out.println("The definition of Test was found!");
        }
}
Run Code Online (Sandbox Code Playgroud)

现在创建一个.jar执行该main方法的可执行文件.你可以在Manifest.txt里面的文件中指定它.jar

Main-Class: NoClassDefFoundErrorExample
Run Code Online (Sandbox Code Playgroud)

现在运行以下命令

javac Test.java
javac NoClassDefFoundErrorExample.java
jar cfm NoClassDefFoundErrorExample.jar Manifest.txt NoClassDefFoundErrorExample.class
java -jar NoClassDefFoundErrorExample.jar
Run Code Online (Sandbox Code Playgroud)

请注意 NoClassDefFoundError

Exception in thread "main" java.lang.NoClassDefFoundError: TestClass
    at NoClassDefFoundErrorExample.(NoClassDefFoundErrorExample.java:2)
Caused by: java.lang.ClassNotFoundException: TestClass
    at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 1 more
Run Code Online (Sandbox Code Playgroud)

  • 堆栈跟踪错误地抱怨“ TestClass”,而应提及“ Test”。 (2认同)

Sar*_*ngh 10

嗯... ClassNotFoundException当运行时试图找到某些人命名的类时String,例如Class.forName(java.lang.String)方法采用字符串参数并尝试查找具有此名称的类.在这种情况下,类名是一个sting,只能在运行时检查.这里的例外清楚地说......没有找到这个"阶级".所以......它可能有两个原因:

原因1.类名不是有效的java类(例如"java.bang.kiting").

// Example    
Class cdef = Class.forName( "java.bang.kiting" );
Run Code Online (Sandbox Code Playgroud)

原因2.类名是一个有效的类...但不知何故,它没有与jar打包或在类路径中没有解析.因此,就运行时所知......它可能是一个错误的类名...类似于案例1.

// Example    
Class cdef =Class.forName( "apache.some.SomeLegitClass" );
Run Code Online (Sandbox Code Playgroud)

对于NoClassDefFoundError使用实际类引用的情况,

// example
import apache.some.SomeLegitClass
SomeLegitClass i = (SomeLegitClass) instanceOfSomeLegitClass;
Run Code Online (Sandbox Code Playgroud)

所以基本上一切都是正确的但不知何故该类没有与jar一起打包(或者更一般地说 - 在类路径中没有解决).在这种情况下,我们得到NoClassDefFoundError.

这里运行时知道该类是有效的,因为它已成功编译...但它找不到"类定义".

  • “这里运行时知道该类是有效的,因为它编译成功......但它找不到“类定义” - 这一行是这个 ans 的本质 (2认同)

Cra*_*ing 7

该差异取决于谁问的类加载:

  • ClassNotFoundException当代码直接尝试加载类时,抛出String表示类的完全限定名称的参数.
    • 例如Class.forName(String),或ClassLoader.loadClass(String).
  • NoClassDefFoundError当JVM被要求间接加载类时抛出.
    • 例如,当A类使用B类而B类不在类路径上时,NoClassDefFoundError将被抛出.