论坛首页 入门技术论坛

NoClassDefFoundError与ClassNotFoundException的疑问

浏览 3426 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-11-07  
NoClassDefFoundError与ClassNotFoundException的区别

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

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. 

As of release 1.4, this exception has been retrofitted to conform to the general purpose exception-chaining mechanism. The "optional exception that was raised while loading the class" that may be provided at construction time and accessed via the getException() method is now known as the cause, and may be accessed via the Throwable.getCause() method, as well as the aforementioned "legacy method."

See Also:
java.lang.Class.forName(java.lang.String)
java.lang.ClassLoader.findSystemClass(java.lang.String)
java.lang.ClassLoader.loadClass(java.lang.String, boolean)


这个描述的大概意思就是当通过一个类名去寻找并装载一个类的时候,如果找不到,则抛出ClassNotFoundException异常。

java.lang.NoClassDefFoundError
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. 


大体意思就是当JVM或者ClassLoader实例试着装载目标class的definition的时候(方法调用,或者构造对象的时候都有可能),但是却找不到lass的definition的时候抛出java.lang.NoClassDefFoundError。 目标的class definition在这个class被编译的时候是存在,但是因为其他原因而找不好了。

根据上面的注释,有一种情况我以为会调用ClassNotFoundException的时候却调用的是java.lang.NoClassDefFoundError。

一个测试类为

package com.liusu.classloader;

public class ClassLoaderTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println("Hello world");
	}

	private static void sleep(int second) {
		try {
			Thread.sleep(1000 * second);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}


进入sh,进入目录结构com.liusu.classloader
javac *.java


然后就在此处,执行:(不设置classpath)
java ClassLoaderTest


抛出:

Exception in thread "main" java.lang.NoClassDefFoundError: ClassLoaderTest (wron
g name: com/liusu/classloader/ClassLoaderTest)

        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:12
4)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:56)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
   发表时间:2008-11-07  
我继续做了个试验:A类调用B类,在第一次调用new B()以后,第二次调用new B()的时候在第一次的10s以后,在这中间我B.class删除了,结果没有出现任何错误。也就是说当CLASS在编译和运行的时候已经被装载和连接过成功过一次以后,已经不依赖于硬盘上的class文件了。也就永远跟NoClassDefFoundError与ClassNotFoundException绝缘了。
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics