您的位置:首页 > Web前端

What is the difference between NoClassDefFoundError and ClassNotFoundException?

2013-05-28 23:19 417 查看
The difference from the Java API Specifications is as follows.

For
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.

For
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.

So, it appears that the
NoClassDefFoundError
occurs
when the source was successfully compiled, but at runtime, the required
class
files
were not found. This may be something that can happen in the distribution or production of JAR files, where not all the required
class
files
were included.

As for
ClassNotFoundException
,
it appears that it may stem from trying to make reflective calls to classes at runtime, but the classes the program is trying to call is does not exist.

The difference between the two is that one is an
Error
and
the other is an
Exception
.
With
NoClassDefFoundError
is
an
Error
and
it arises from the Java Virtual Machine having problems finding a class it expected to find. A program that was expected to work at compile-time can't run because of
class
files
not being found, or is not the same as was produced or encountered at compile-time. This is a pretty critical error, as the program cannot be initiated by the JVM.

On the other hand, the
ClassNotFoundException
is
an
Exception
,
so it is somewhat expected, and is something that is recoverable. Using reflection is can be error-prone (as there is some expectations that things may not go as expected. There is no compile-time check to see that all the required classes exist, so any problems
with finding the desired classes will appear at runtime.

首先:

ClassNotFoundException直接继承与Exception,它是一个checked的异常。

NoClassDefFoundErr 继承自Error->LinkageError ,它是一个unchecked的异常。

下面让我们看一下两个异常在API文档中的说明:

当应用尝试用字符串名称通过下面的方法装载一个类时这个类的定义却没有找到时会抛出的异常。

Class.forName

ClassLoader.findSystemClass

ClassLoader.loadClass

NoClassDefFoundErr:

当JVM或者ClassLoader实例尝试装载一个类的定义(这通常是一个方法调用或者new表达式创建一个实例过程的一部分)而这个类定义并没有找时所抛出的错误。

当编译的时候可以找到这个类的定义,但是以后这个类不再存在。

ClassNotFoundException异常只出现在你的应用程序主动的装载类的过程中,这个异常很多时候出现在我们的应用框架在初始化或者运行中动态装载已配置的类的过程中。这种情况下我们应该首先检查我们的配置或者参数是否错误,是否企图装载一个并不存在的类,如果配置没有错误,我们就应该查看Classpath是否配置错误而导致ClassLoader无法找到这个类,也应该检查要装载的类是否在一个jar包中而我们在引入这个jar包的过程中是否有遗漏或错误(这里jar包的版本也是一个需要格外注意的问题,很多时候混乱的jar包版本会造成太多的麻烦)。

NoClassDefFoundErr异常一般出现在我们编译环境和运行环境不一致的情况下,就是说我们有可能在编译过后更改了Classpath或者jar包所以导致在运行的过程中JVM或者ClassLoader无法找到这个类的定义。

以简单而经典的 “HelloWorld.java”为例

不含包层次的HelloWorld.java

  public classHelloWorld

{

publicstatic void main(String[] args)

{

System.out.println("Hello World!");

}

}

  保存在E:\java\src下,命令行下,改变当前路径到:E:\java\src,使用javac命令编译:

  E:\java\src>javac HelloWorld.java

  运行:

  E:\java\src>java HelloWorld

  屏幕打印出:

  Hello World!

  初学者常犯的错误

  1.运行时,带了.class后缀

  如果你试图使用如下命令:

  E:\java\src>javaHelloWorld.class

  系统会误认为你运行的是HelloWorld包下的名为class的类文件,会到系统的CLASSPATH下(一般都包括当前目录)企图寻找HelloWorld.class.class这样的类,这样的类当然不存在了;并且也不可能存在,因为class是关键字,不能作为一个类的名字。所以会报如下错误信息:

  Exception in thread "main"java.lang.NoClassDefFoundError: HelloWorld/class

  2.文件名大小写错误

  对于像Windows这样的系统,编译时可以不关心大小写。比如编译HelloWorld.java时,也可以使用:

  E:\java\src>javachelloworld.java

  也可以编译通过,但产生的类文件仍然是和源文件相符的:HelloWorld.class。

  但在运行时一定要注意大小写,比如试图使用如下命令运行:

  E:\java\src>javahelloworld

  将报类似于1中的错误:

  Exception in thread "main"java.lang.NoClassDefFoundError: helloworld (wrong name:HelloWorl
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: