ClassNotFoundException和NoClassDefFoundError

定義:html

對於術語的定義,最原汁原味的仍是官方文檔。java

關於ClassNotFoundExceptionJavaDoc裏這麼描述:express

Thrown when an application tries to load in a class through its string name using:api

  • The forName method in class Class.
  • The findSystemClass method in class ClassLoader .
  • The loadClass method in class ClassLoader.

but no definition for the class with the specified name could be found.oracle

關於NoClassDefFoundErrorJavaDoc裏這麼描述:app

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 the new 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.spa


樣例:命令行

若是隻看官方定義,不容易明白(我就是這樣的),看例子:code

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

相關文章
相關標籤/搜索