ClassNotFoundException v/s NoClassDefFoundError

2021-04-09 18:11:42 浏览数 (1)

在这个小节里,我们讨论一下ClassNotFoundException与NoClassDefFoundError的区别。

通常这两种情况都是由于程序执行期间缺少必需的.class文件,但它们之间存在差异。

ClassNotFoundException

NoClassDefFoundError

这通常发生在程序执行时,使用class load 语句加载缺失的.class文件:Class.forName(“class.name”);ClassLoader.loadClass(“class.name”);ClassLoader.findSystemClass(“class.name”);理由:由于运行时未更新JAR文件而执行程序,类路径中缺少必需的文件。

这两个错误相似,但是不同之处在于必需的.class文件在编译时可用,在运行时丢失。可能的原因:它在编译后被删除可能存在版本不匹配

完全限定的类名为java.lang.ClassNotFoundException

完全限定的类名为java.lang.NoClassDefoundError

它属于异常类别,即java.lang.Exception的直接子类。

它属于错误类别,即java.lang.Error, java.lang.LinkageError的子类。

它是一个Checked Exception,因此每当遇到如第1点所述的类装入语句时,都需要处理它。

所有Error都属于unchecked Exception类别,因此NoClassDeffoundError也属于unchecked Exception。

当检查异常时,程序员可以使用try catch块或声明throws子句来提供处理代码。因此,它是可被解决的。

程序执行过程中Java Runtime System 引发的错误因此,它难以复现。

示例1

示例2

  • Class.forName(“class.name”);
  • ClassLoader.loadClass(“class.name”);
  • ClassLoader.findSystemClass(“class.name”);

理由:由于运行时未更新JAR文件而执行程序,类路径中缺少必需的文件。这两个错误相似,但是不同之处在于必需的.class文件在编译时可用,在运行时丢失。 可能的原因:

  • 它在编译后被删除
  • 可能存在版本不匹配

完全限定的类名为java.lang.ClassNotFoundException完全限定的类名为java.lang.NoClassDefoundError它属于异常类别,即java.lang.Exception的直接子类。它属于错误类别,即java.lang.Error, java.lang.LinkageError的子类。它是一个Checked Exception,因此每当遇到如第1点所述的类装入语句时,都需要处理它。所有Error都属于unchecked Exception类别,因此NoClassDeffoundError也属于unchecked Exception。当检查异常时,程序员可以使用try catch块或声明throws子句来提供处理代码。 因此,它是可被解决的。程序执行过程中Java Runtime System 引发的错误 因此,它难以复现。示例1示例2

示例1:ClassNotFoundException上的演示示例:

public class JdbcConnectionExample { public static void main(String[] args) { // declare variables // Step 1: Loading or registering Oracle JDBC driver class try { Class.forName("oracle.jdbc.driver.OracleDriver"); } catch(ClassNotFoundException cnfex) { System.out.println("Problem in loading Oracle JDBC driver"); cnfex.printStackTrace(); } // Step 2: Opening database connection } }

输出结果:

java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver Problem in loading Oracle JDBC driver at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Unknown Source) at in.bench.resources.top.exception.in.java.JdbcConnectionExample .main(JdbcConnectionExample.java:11)

在上面的例子中, 我们正在尝试使用Class.forName()静态方法加载Oracle数据库的驱动程序文件,但它在运行时不可用。 这类异常的可能原因,执行JDBC程序而不使用所需的JAR文件更新类路径, 解决方案:要纠正这个异常,只需将必需的ojdbc14.jar包含到类路径中,然后执行相同的程序。

示例2:NoClassDefoundError的演示示例:

public class SimilarException { // using below declared TestFile class static TestFile tf = new TestFile(); public static void main(String[] args) { // invoke method tf.display(); } } class TestFile { public void display() { System.out.println("Display message"); } }

运行结果:

java.lang.NoClassDefFoundError: in/bench/resources/top/exception/in/java/TestFile at in.bench.resources.top.exception.in.java.SimilarException.<clinit>( SimilarException.java:6) Caused by: java.lang.ClassNotFoundException: in.bench.resources.top.exception.in.java.TestFile at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) ... 1 more Exception in thread "main"

在上面的例子中,我们编译后故意删除testfile.class以显示此异常类型. 我们正试图执行一个程序,但是classpath中缺少必须的类文件TestFile.class。 此异常类型的可能原因,在编译期间存在必需的文件,但在执行同一程序时丢失了该文件 上面的程序显示“has-a”关系,编译成功,而在程序执行期间,JVM找不到所需的.class文件。

0 人点赞