NoClassDefFoundError
如果Java虚拟机或ClassLoader实例尝试在加载类的定义(作为正常方法调用的一部分或使用new表达式创建新实例的一部分)时找不到该类的定义,则会抛出此异常。
当当前执行的类编译时,正在搜索的类定义存在,但是现在无法找到该定义。
ClassNotFoundException
当应用程序尝试通过其字符串名称加载类时引发:class Class中的forName方法。 class ClassLoader中的findSystemClass方法。 class ClassLoader中的loadClass方法。
您必须了解,JVM无法意识到您删除的类的定义无法找到,因为自身找不到该类,这会自动引发ClassNotFoundException异常。
此异常发生在运行时,因此编译是否成功都无关紧要,由于您删除了文件,因此找不到并引发异常。
请注意,NoClassDefFoundError实际上不是异常,它是从LinkageError派生的错误,而ClassNotFoundException直接从java.lang.Exception派生。
总之,NoClassDefFoundError全局简单地意味着JVM在运行时尝试访问根据编译的代码应该存在但实际上不存在(或不在类路径中)的内容。
复现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();
}
}
}
重现NoClassDefFoundError的示例:
创建一个简单的类Test
。
public class Test {
public Test() {
System.out.println("A new instance of the Test class was created!");
}
}
还有一个名为 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!");
}
}
现在创建一个可执行的 .jar
文件,其中包含执行 main
方法。您可以在 .jar
文件内的 Manifest.txt
文件中指定它。
Main-Class: NoClassDefFoundErrorExample
现在运行以下命令
javac Test.java
javac NoClassDefFoundErrorExample.java
jar cfm NoClassDefFoundErrorExample.jar Manifest.txt NoClassDefFoundErrorExample.class
java -jar NoClassDefFoundErrorExample.jar
请注意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
import com.random.blah.B;
,会发生什么。 - Chris Fei