跳到主要内容

ClassNotFoundException与NoClassDefFoundError【译】

· 阅读需 4 分钟

ClassNotFoundExceptionNoClassDefFoundError 都是某个类在运行时没有找到时出现的,但它们发生的场景不同。

ClassNotFoundException 是一个异常,当你在运行时使用 Class.forName()loadClass() 方法尝试去加载一个类且这个类没有在 classpath 下找到时会出现该异常。

NoClassDefFoundError 是一个错误,当某个类在编译时存在但在运行时丢失时会出现该错误。

ClassNotFoundException

ClassNotFoundException 是一个运行时异常,当应用程序在运行时使用 Class.forName()loadClass()findSystemClass() 方法尝试去加载一个类,并且这个类在 classpath 下找不到时会抛出该异常。举个例子,当你尝试连接到 MySQL 或 Oracle 数据库,且你还没有将需要的 JAR 文件更新到 classpath 下时,你可能就碰到过这个异常。在大多数时候,这个异常发生在当你尝试去运行一个应用程序但还没有将需要的 JAR 文件更新到 classpath 时。

例如,如果提到的类 "oracle.jdbc.driver.OracleDriver" 没有在 classpath 下找到,下面这个程序会抛出 ClassNotFoundException

public class MainClass {
public static void main(String[] args) {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}

如果你没有将需要的 JAR 文件更新到 classpath,运行上面的程序你会遇到如下异常:

java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at MainClass.main(MainClass.java:4)

NoClassDefFoundError

NoClassDefFoundError 是一个错误,当 Java 运行时系统尝试去加载某个类的定义,但这个类的定义不可用时,会抛出这个错误。需要的类定义在编译时是存在的,但在运行时丢失。例如,编译下面的程序:

class A {
// some code
}

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

当你编译完上面的程序,会生成两个 .class 的文件。其中一个是 A.class,另一个是 B.class。如果你移除 A.class 文件再运行 B.class,Java 运行时系统会抛出 NoClassDefFoundError,如下:

Exception in thread "main" java.lang.NoClassDefFoundError: A
at B.main(B.java:7)
Caused by: java.lang.ClassNotFoundException: A
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 1 more

总结

ClassNotFoundExceptionNoClassDefFoundError
它是个异常,是一种java.lang.Exception它是个错误,是一种java.lang.Error
它发生在应用程序在运行时尝试加载一个没有更新到 classpath 中的类的时候。它发生于 Java 运行时系统不能找到一个类的定义,类的定义在编译时存在却在运行时丢失。
它由应用程序自己抛出。通过类似于 Class.forName(), loadClass()findSystemClass() 之类的方法抛出。它由 Java 运行时系统抛出。
它发生于需要的 JAR 文件没有更新到 classpath。它发生在运行时需要的类定义丢失时。

参考文献

ClassNotFoundException vs. NoClassDefFoundError - DZone Java