首页 > 其他分享 >NoClassDefFoundError 和 ClassNotFoundException 有什么区别

NoClassDefFoundError 和 ClassNotFoundException 有什么区别

时间:2022-12-21 14:34:41浏览次数:42  
标签:lang ClassNotFoundException java 区别 NoClassDefFoundError Class 加载

image.pngimage.png 从类继承层次上来看,ClassNotFoundException是从Exception继承的,所以ClassNotFoundException是一个检查异常。NoClassDefFoundError是从Error继承的。和ClassNotFoundException相比,明显的一个区别是,NoClassDefFoundError并不需要应用程序去关心catch的问题。

NoClassDefFoundError

当JVM在加载一个类的时候,如果这个类在编译时是可用的,但是在运行时找不到这个类的定义的时候,JVM就会抛出一个NoClassDefFoundError错误。比如当我们在new一个类的实例的时候,如果在运行时类找不到,则会抛出一个NoClassDefFoundError的错误。通常发生在执行动态代码块或者初始化静态字段时报了异常,从而导致类初始化失败而引发NoClassDefFoundError。案例如下:

public class ClassWithInitErrors {
    static int data = 1 / 0;
}

public class NoClassDefFoundErrorTest {
    public ClassWithInitErrors getClassWithInitErrors() {
        ClassWithInitErrors test = new ClassWithInitErrors();
        return test;
    }

    @Test(expected = NoClassDefFoundError.class)
    public void givenInitErrorInClass_whenloadClass_thenNoClassDefFoundError() {
        NoClassDefFoundErrorTest sample
                = new NoClassDefFoundErrorTest();
        sample.getClassWithInitErrors();
    }
}

执行程序后会出现如下错误:

java.lang.Exception: Unexpected exception, expected<java.lang.NoClassDefFoundError> but was<java.lang.ExceptionInInitializerError>

	at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:28)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
	...  more
Caused by: java.lang.ArithmeticException: / by zero
	at com.zjq.dailyrecord.throwable.ClassWithInitErrors.<clinit>(ClassWithInitErrors.java:4)
	... 25 more

ClassNotFoundException

当应用程序运行的过程中尝试使用类加载器去加载Class文件的时候,如果没有在classpath中查找到指定的类,就会抛出ClassNotFoundException。一般情况下,当我们使用Class.forName()或者ClassLoader.loadClass以及使用ClassLoader.findSystemClass()在运行时加载类的时候,如果类没有被找到,那么就会导致JVM抛出ClassNotFoundException。 最简单的,当我们使用JDBC去连接数据库的时候,我们一般会使用Class.forName()的方式去加载JDBC的驱动,如果我们没有将驱动放到应用的classpath下,那么会导致运行时找不到类,所以运行Class.forName()会抛出ClassNotFoundException。案例如下:

public class ClassNotFoundExceptionTest {
    public static void main(String[] args) {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

执行后输出:

java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:264)
	at com.zjq.dailyrecord.throwable.ClassNotFoundExceptionTest.main(ClassNotFoundExceptionTest.java:6)

总结区别

ClassNotFoundException NoClassDefFoundError
从java.lang.Exception继承,是一个Exception类型 从java.lang.Error继承,是一个Error类型
当动态加载Class的时候找不到类会抛出该异常 当编译成功以后执行过程中Class找不到导致抛出该错误
一般在执行Class.forName()、ClassLoader.loadClass()或ClassLoader.findSystemClass()的时候抛出 由JVM的运行时系统抛出

解决办法

他们的主要原因是运行时类路径中类文件不可用。 下面是几点具体的原因:

  1. 排查所需的jar包是否在类路径中,如果没有就添加进去。
  2. 如果发现类在classpath里面,很有可能是classpath被重写了,需要再次确定应用准确的classpath
  3. 依赖包发生了冲突,比如应该依赖高版本jar包,但又其它包传递依赖了低版本jar包,导致高版本中某些类找不到。
  4. 如果应用中用到了多个类加载器,一个类加载器加载的类,无法再其他的类加载器中使用。

本文内容到此结束了, 如有收获欢迎点赞

标签:lang,ClassNotFoundException,java,区别,NoClassDefFoundError,Class,加载
From: https://blog.51cto.com/zhanjq/5959915

相关文章

  • 进程与线程的区别,如何创建线程类
    ......
  • 流媒体服务器与视频服务器的区别是什么
    1、流媒体服务器主要是连接端到端,负责音视频流的传输,包括采集、转码、推流,存储等功能。可部署在局域网和互联网,实现私有云和公有云应用,流媒体服务器在单设备上可实现10000......
  • 彻底搞懂@JsonFormate和@DateTimeFormate区别和用法
    问题今天在使用@JsonFormate和@DateTimeFormate发现出现了非常多意想不到的问题;如:1)使用ajax提交json数据时,明明提交的字符串是@DateTimeFormate中规定的类型却报错400;2)没写@......
  • java.lang.ClassNotFoundException
    当你用Eclipse或者MyEclipse运行javaweb项目时,发现连接数据库失败,出现提示java.lang.ClassNotFoundException,你确定你的jar包添加了,那么很有可能是你项目的本地lib没有......
  • 实现继承与接口继承区别
    实现继承通常情况下表现为对抽象类的继承,而其与接口继承在规则上有以下几点归纳:·抽象类适合于有族层概念的类间关系,而接口最适合为不同的类提供通用功能。·接口着重于C......
  • 什么是宏任务和微任务,两者的区别
    微任务:promise,async/await>>>DOM渲染前触发宏任务:setTimeout,setInterval,Ajax,DOM事件>>>DOM渲染后触发为什么微任务执行的更早?答:微任务有专门的微任务队列,其执行......
  • Python Type Hint中Optional[str]=None和str=None的区别
    PythonTypeHint中Optional[str]=None和str=None的区别1问题来源在读到FluentPython,2edEdition,P260时产生了一些疑问:在Python中使用typehint时,以下两个声明有......
  • java.lang.ClassNotFoundException: javax.servlet.Filter
    java.lang.ClassNotFoundException:javax.servlet.Filter:有两个原因:(1)在maven中的作用域,不能是provided,需要是compile就是默认的scope(2)spring-boot-starter-tomcat的版本bu......
  • forward和redirect的区别
    Forward:不需要客户端配合,全服务器端动作。只能forward到同servlet服务器的页面。forward后,执行浏览器上的“后退”操作,会回到上一个页面。如果提交表单页面没有跳转,刷新页......
  • Linux软件安装包中devel与非devel包之间的区别
    带devel(develop)的包,俗称开发包。功能上与普通包相同,但体积更大使用rpm-qi看看这两类包的区别:#rpm-qiglibc-devel-2.12-1.149.el6.x86_64Name:glibc-devel......