ClassNotFoundException和NoClassDefFindError区别

ClassNotFoundException和NoClassDefFindError这两者之间的区别。这是一个常见的面试题,这两者发生的原因都是因为想要寻找一个目标类,但是目标类在classpath下并不存在而产生的问题或者是异常。但是二者在产生的原因上有很大的区别,同时二者本质也不同,一个是异常,而一个是致命错误

ClassNotFoundException通常发生在使用反射等机制,通过字符串名称去查找一个具体的类,但是发现它并不存在。最典型的使用场景就是咱们通过class.forName或者通过咱们类加载器的loadClass去加载一个类的时候,发现这个类并不存在,此时就会发生相关的异常,而NoClassDefFindError这种致命错误发生的原因往往是因为在使用new等关键字进行对象创建的时候,发现编译时候存在该类,而运行的时候该类不存在,啥意思?就是你写了这么一行代码叫User user = new User() ,在编译的时候这个user类是存在的,但是运行的时候这个user类就不存在了,就会发生致命错误,你new关键字后边都没有这个类了,程序还怎么去运行?那有的小伙伴可能会问,什么情况下才会出现编译时存在而运行时不存在的问题?当然说到这儿咱们也就理解了这种致命错误发生的原因就是字节码文件,就是.class文件的丢失,那么丢失不外乎有两种情况,第一种人为的主动的把它给排除掉,把它摘除了,第二种因为磁盘传输等原因导致这个类文件损坏或者丢失。给大家举一个简单的例子,比如说对于咱们的一个工程,这个工程是一个最简单最朴素的工程,不是一个maven工程,我们这个工程需要引入一个数据源,假设我们要引入一个hikari的数据源。hikari的作者在编写hikari的时候会引用到第三方的,比如说一些日志相关的一些框架,然而hikari的作者在对自己的产品进行编译打包之后,为了让自己的产品功能更加的聚焦,体积更加的小,于是就把一些第三方的日志相关的jar包就给它排除掉了。如果在咱们的工程当中仅仅依赖于hikari,你在启动的时候,你在运行的时候,你会发现它就会报这个异常,这个现象在maven工程里边不存在,因为maven里边有依赖传递,它会自动的将第三方的依赖引入进来。最后还可能因为一些版本冲突的问题,比如说A依赖与B的2.0版本,但是在咱们的工程当中只有B的1.0版本,在2.0版本当中可能会使用一些新的类,但是呢,在咱们当前的工程底下却没有,而我们所获取的jar包都是编译后的产品,所以只有在运行的时候这个错误才有可能发生。那么最后因为网络传输因为磁盘文件损坏等原因导致的class字节码损坏,那么我们就不用详细介绍了。最后咱们再给大家举一个例子,和大家一起探讨一下这个异常和错误的问题,他们有什么本质的区别?对于ClassNotFoundException,相当于你去一个公司找一个名字叫张三的人,但是没找到,没找到的原因可能是因为这个公司本来就没有张三,也有可能张三今天不在公司,对于公司整体的运作而言,今天的张三在与不在可能没有什么影响,所以它仅仅是异常。而对于NoClassDefFindError这种致命问题,它所产生的原因更像张三现在正在工作当中,但是突然间消失了,本来需要张三,但是他不在了,整个工程都因为他而耽误了,所以他是一个致命错误!(完)

ps: 如果有任何疑问,欢迎评论区给我留言


已有 0 条评论

    感谢参与互动!