前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >ClassNotFoundException 和 NoClassDefFoundError 的区别

ClassNotFoundException 和 NoClassDefFoundError 的区别

作者头像
阿凯
发布于 2018-06-29 04:35:05
发布于 2018-06-29 04:35:05
6.6K00
代码可运行
举报
文章被收录于专栏:程序员阿凯程序员阿凯
运行总次数:0
代码可运行

Java 面试中有个很常见的问题:请对比 Exception 和 Error,另外一个,“运行时异常” 与 “一般异常” 有什么区别?

今天在看 「极客时间」的 《Java 核心技术 36 讲》 中又有提到。

大家都熟悉的典型回答:

  1. Exception 和 Error 都是继承了 Throwable 类,在 Java 中只有 Throwable 类型的实例才可以被抛出(throw)或者捕获(catch),它是异常处理机制的基本组成类型。
  2. Exception 和 Error 体现了 Java 平台设计者对不同异常情况的分类。Exception 是程序正常运行中,可以预料的意外情况,可能并且应该被捕获,进行相应处理。
  3. Error 是指在正常情况下,不大可能出现的情况,绝大部分的 Error 都会导致程序(比如 JVM 自身)处于非正常的、不可恢复状态。既然是非正常情况,所以不便于也不需要捕获,常见的比如 OutOfMemoryError 之类,都是 Error 的子类。
  4. Exception 又分为可检查(checked)异常和不检查(unchecked)异常,可检查异常在源代码里必须显式地进行捕获处理,这是编译期检查的一部分。前面我介绍的不可查的 Error,是 Throwable 不是 Exception。
  5. 不检查异常就是所谓的运行时异常,类似 NullPointerException、ArrayIndexOutOfBoundsException 之类,通常是可以编码避免的逻辑错误,具体根据需要来判断是否需要捕获,并不会在编译期强制要求。

在杨老师分析这道题时,有提到,关于异常需要掌握的两个方面:

这里提出了一个问题:ClassNotFoundException 和 NoClassDefFoundError 有什么区别

在这之前,自己没有遇到过这个问题,就借此机会做下思考:

ClassNotFoundException 和 NoClassDefFoundError

首先,正如它们的名字所说明的:

NoClassDefFoundError是一个错误(Error),而 ClassNOtFoundException 是一个异常

在Java中错误和异常是有区别的:我们可以从异常中恢复程序,但却不应该尝试从错误中恢复程序。

ClassNotFoundException 产生的原因:

Java支持使用 Class.forName 方法来动态地加载类,任意一个类的类名如果被作为参数传,递给这个方法都将导致该类被加载到 JVM 中。如果这个类在类路径中没有被找到,那么此时就会在运行时抛出 ClassNotFoundException 异常。

要解决这个问题,就要确保所需的类连同它依赖的包存在于类路径中。当 Class.forName 被调用的时候,类加载器会查找类路径中的类,如果找到了那么这个类就会被成功加载,如果没找到,那么就会抛出ClassNotFountException。

除了 Class.forName,ClassLoader.loadClass、ClassLOader.findSystemClass 在动态加载类到内存中的时候也可能会抛出这个异常。

另外还有一个导致 ClassNotFoundException 的原因就是:当一个类已经某个类加载器加载到内存中了,此时另一个类加载器又尝试着动态地从同一个包中加载这个类。

由于类的动态加载在某种程度上是被开发者所控制的,所以他可以选择 catch 这个异常然后采取相应的补救措施。

NoClassDefFoundError 产生的原因:

当 Java 虚拟机 或 ClassLoader 实例试图在类的定义中加载(作为通常方法调用的一部分,或者是使用 new 来创建新的对象)时,却找不到类的定义(要查找的类在编译的时候是存在的,运行的时候却找不到了),抛出此异常。

即当前执行的类被编译时,所搜索的类定义存在,但无法再找到该定义。

这个错误往往是你使用 new 操作符来创建一个新的对象,但却找不到该对象对应的类。这个时候就会导致NoClassDefFoundError

由于 NoClassDefFoundError 是有 JVM 引起的,所以不应该尝试捕捉这个错误。

解决这个问题的办法就是:查找那些在开发期间存在于类路径下但在运行期间却不在类路径下的类

二者的区别

ClassNotFoundException 发生在装入阶段。

当应用程序试图通过类的字符串名称,使用常规的三种方法装入类,但却找不到指定名称的类定义时就抛出该异常。

NoClassDefFoundError 当目前执行的类已经编译,但是找不到它的定义时。也就是说你如果编译了一个类B,在类A中调用,编译完成以后,你又删除掉B,运行A的时候那么就会出现这个错误。

加载时从外存储器找不到需要的 Class 就出现 ClassNotFoundException

连接时从内存找不到需要的 class 就出现 NoClassDefFoundError

写在最后:

异常的出现让我们编写的程序运行起来更加的健壮,同时为程序在调试、运行期间发生的一些意外情况,提供了补救机会; 不要推诿或延迟处理异常,就地解决最好,并且需要实实在在的进行处理,而不是只捕捉,不动作, 如无必要,勿用异常。

关于异常的处理,留一个思考题给大家:

下面的代码反映了异常处理中哪些不当之处?欢迎留言讨论。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1try {
2  // 业务代码
3  // …
4  Thread.sleep(1000L);
5} catch (Exception e) {
6  // Ignore it
7}

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-05-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员阿凯 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
React Hooks 源码解析(3):useState
React 源码版本: v16.11.0 源码注释笔记:airingursb/react 在写本文之前,事先阅读了网上了一些文章,关于 Hooks 的源码解析要么过于浅显、要么就不细致,所以本文着重讲解源码,由浅入深,争取一行代码也不放过。那本系列讲解第一个 Hooks 便是 useState,我们将从 useState 的用法开始,再阐述规则、讲解原理,再简单实现,最后源码解析。另外,在本篇开头,再补充一个 Hooks 的概述,前两篇限于篇幅问题一直没有写一块。 注:距离上篇文章已经过去了两个月,这两
QQ音乐前端团队
2019/12/03
1.9K1
React Hooks 源码解析(3):useState
带你深入了解 useState
为什么 react 16 之前的函数组件没有状态? 众所周知,函数组件在 react 16 之前是没有状态的,组件状态只能通过 props 进行传递。 写两个简单的组件,一个类组件和一个函数组件: const App = () =><span>123</span>; class App1 extends React.Component {  constructor(props) {    super(props);    this.state = {      a: 1,    }  }  
用户1097444
2022/06/29
1.8K0
带你深入了解 useState
烧脑预警,这波心智负担有点重,深度探讨 useState 的实现原理
在前面的一篇文章中,我们介绍了 Fiber 的详细属性所代表的含义。在函数式组件中,其中与 hook 相关的属性为 memoizedState
用户6901603
2024/01/10
3420
烧脑预警,这波心智负担有点重,深度探讨 useState 的实现原理
React源码分析(三):useState,useReducer
大家都知道hooks是在函数组件的产物。之前class组件为什么没有出现hooks这种东西呢?
goClient1992
2022/09/27
9200
从React源码来学hooks是不是更香呢
要理解 hooks 的执行过程,首先想要大家对 hooks 相关的数据结构有所了解,便于后面大家顺畅地阅读代码。
goClient1992
2022/10/04
7150
React 架构的演变 - Hooks 的实现
“这是这个系列的最后一篇文章了,终于收尾了? 。 React Hooks 可以说完全颠覆了之前 Class Component 的写法,进一步增强了状态复用的能力,让 Function Compone
桃翁
2020/11/11
5780
React 架构的演变 - Hooks 的实现
ReactHooks源码解析之useState及为什么useState要按顺序执行
从本篇开始,我们讲 React-Hooks 最常用的几个函数,先通过例子来看下React.useState():
进击的小进进
2020/05/17
3.8K0
深入react源码看setState究竟做了什么?
在深究 React 的 setState 原理的时候,我们先要考虑一个问题:setState 是异步的吗?
flyzz177
2022/10/18
7320
React源码解析之FunctionComponent(上)
在 React源码解析之workLoop 中讲到当workInProgress.tag为FunctionComponent时,会进行FunctionComponent的更新:
进击的小进进
2019/12/02
1K0
从react源码看hooks的原理_2023-03-01
其实hooks的定义都来自dispatcher,那我们根据Dispatcher依次去看看他们的实际实现。
flyzz177
2023/03/01
8770
从React源码来学hooks是不是更香呢_2023-02-28
要理解 hooks 的执行过程,首先想要大家对 hooks 相关的数据结构有所了解,便于后面大家顺畅地阅读代码。
goClient1992
2023/02/28
7520
从源码理解 React Hook 是如何工作的
React Hook 是 React 16.8 后新加入的黑魔法,让我们可以 在函数组件内保存内部状态。
前端西瓜哥
2022/12/21
1.3K0
从react源码看hooks的原理
其实hooks的定义都来自dispatcher,那我们根据Dispatcher依次去看看他们的实际实现。
flyzz177
2022/10/18
9040
【React】946- 一文吃透 React Hooks 原理
之前的两篇文章,分别介绍了react-hooks如何使用,以及自定义hooks设计模式及其实战,本篇文章主要从react-hooks起源,原理,源码角度,开始剖析react-hooks运行机制和内部原理,相信这篇文章过后,对于面试的时候那些hooks问题,也就迎刃而解了。实际react-hooks也并没有那么难以理解,听起来很cool,实际就是函数组件解决没有state,生命周期,逻辑不能复用的一种技术方案。
pingan8787
2021/05/14
2.8K0
【React】946- 一文吃透 React Hooks 原理
相关推荐
React Hooks 源码解析(3):useState
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文