定义:
对于术语的定义,最原汁原味的还是官方文档。
关于ClassNotFoundException,JavaDoc里这么描述:
Thrown when an application tries to load in a class through its string name using:
- The
forName
method in classClass
.- The
findSystemClass
method in classClassLoader
.- The
loadClass
method in classClassLoader
.but no definition for the class with the specified name could be found.
关于NoClassDefFoundError,JavaDoc里这么描述:
Thrown if the Java Virtual Machine or a
ClassLoader
instance tries to load in the definition of a class (as part of a normal method call or as part of creating a new instance using thenew
expression) and no definition of the class could be found.The searched-for class definition existed when the currently executing class was compiled, but the definition can no longer be found.
样例:
如果只看官方定义,不容易明白(我就是这样的),看例子:
public class A {
public static void main(String[] args) {
try {
B b = new B(); //NoClassDefFoundError
} catch(Throwable e) {
e.printStackTrace();
}
System.out.println("----------------------------");
try {
Class b = Class.forName("B");//ClassNotFoundException
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("----------------------------");
try {
ClassLoader loader = A.class.getClassLoader();
loader.loadClass("B");//ClassNotFoundException
} catch(Throwable e) {
e.printStackTrace();
}
}
}
class B {
}
这里定义了两个类A和B,其中在A中的main方法中使用了B。
如果使用Eclipse工具编写这个类,编写完按下保存后,Eclipse会自动编译这两个类生成A.class和B.class。
如果使用cmd命令行,则需要手动编译这两个类。
接下来,我们把编译好的B.class手动删掉,之后再执行A的main方法:
可以看到,new B()这一句抛出了NoClassDefFoundError,而Class.forName("B")和ClassLoader.loadClass("B")这两句则抛出了ClassNotFoundException。
原因就是JavaDoc里提到的:当使用类名字符串去调用Class.forName等方法来加载一个类时,如果找不到这个类,则抛出ClassNotFoundException。如果JVM尝试去加载一个类(普通方法调用或者使用new关键字创建对象),而这个类又不存在时,则抛出NoClassDefFoundError。
区别:
一个是Error,一个是Exception。
通过类名,手动调用方法去加载不存在的类,抛出ClassNotFoundException;而如果是JVM调用方法加载不存在的类,抛出NoClassDefFoundError。
总结:
ClassNotFoundException :
Thrown when an application tries to load in a class through its name, but no definition for the class with the specified name could be found
NoClassDefFoundError :
Thrown if the Java Virtual Machine tries to load in the definition of a class and no definition of the class could be found.
参考:
http://stackoverflow.com/questions/1457863/what-causes-and-what-are-the-differences-between-noclassdeffounderror-and-classn
http://www.javaroots.com/2013/02/classnotfoundexception-vs.html