java的异常体系

java异常体系

缘由

学习spring源码的时候,看到了NestedRuntimeException,整理一下java异常体系吧。

java异常的分类

如果要熟悉java的异常体系,首先就要从java.lang.Throwable入手,Throwable类是java语言中所有错误和异常的超类,无论是java虚拟机还是程序抛出的异常都是Throwable的子类或者间接子类。

同样我们使用的try{…}catch(…){…}语句,能够捕捉的也必然是该类或其子类以及间接子类。

对于异常的分类,从不同的角度我们可以将其划分出来不同的类别。

按照UML进行分类

如果按照异常体系的代码涉及上来看,我们可以将异常分为两大家族,Error家族和Exception家族。 Throwable Uml

Error

其中Error家族比较暴躁,他们是严重问题的代名词,当Error家族的成员出现的时候,往往也就意味着底层资源出现了问题,比如硬件问题,资源问题等,所以在正常的场景下,程序员不应该捕捉或者处理他们,因为对于Error家族的异常,一般我们就算捕获了,也做不了什么。

但是,凡事都有例外,Error家族里面有一个比较特殊的成员ThreadDeath,它代表的意义没有Error家族中的其他成员那么严重,算是一个比较正常的错误,

ThreadDeath异常的触发条件很简单,当我们调用Thread的stop()方法的时候,对应的线程就会抛出ThreadDeath错误。

对于这个错误我们可以捕捉他,进行一些操作,但是我们必须要再次抛出这个错误,因为只有这样,这个线程才会真正的停止。

Exception

Exception家族的异常就比较温和,他通常表示的是合理的应用程序发生的错误,这种错误往往是程序员意料之中的,通常我们都会捕获Exception家族的异常,并进行处理。

Exception家族的异常往往也是我们主要接触的异常,比如空指针,角标越界之类的异常。

按照异常发现时期分类

对于异常的分类,出于编译时期就能够检查出异常的目的,我们可以把异常分为两类,检查异常和非检查异常。 两者的分类按照下列规则:

Throwable家族中除RuntimeException 系列和Error系列之外的所有异常都认为是编译异常,也就是检查异常。

这个分类其实很符合事实逻辑,关于Error家族的错误,他们通常是底层JVM发生了错误,这种错误一旦发生,往往是程序员不可控制的,Error级别的错误很少出现,因此程序员可以减少关注Error级别的错误。

而RuntimeException系列的错误,就和他的名称一样,往往代表着运行时发生的错误,在编译期间往往很难发现。

StackTraceElement

当我们的java程序报错时,程序往往会给我们提供比较详细的错误堆栈信息,来方便我们排查处理问题,而这个堆栈信息则是由一个我们虽然经常接触但却不太熟悉的类组成的——StackTraceElement

StackTraceElement表示堆栈跟踪数据中的一个元素,他本身代表着一个堆栈帧。

我们使用的JVM是一个堆栈虚拟机,他会为每个线程都开辟一个堆栈空间,这个堆栈空间就像一个个小抽屉一样,线程中的代码就执行在这个小抽屉里,在小抽屉上面还有一个标签,这个标签记录了当前线程的状态,而这个标签就是堆栈帧。

StackTraceElement提供了四个属性来记录所需的堆栈数据:

字段描述
declaringClass方法调用者的类名
methodName方法名
fileName文件名
lineNumber行号
并且该类定制Object的hashCode,equals,toString方法。

Throwable

说了这么多异常相关的内容,最后总结的时候还是要回到Throwable类上面,通过前面的内容我们已经能够确定一个概念:

Throwable是所有异常的超级父类了,在java中的异常必然会是该类或其衍生类。

在确定该概念之后,我们再去观察Throwable的构造方法,会发现所有的构造方法都必然会调用一个叫做fillInStackTrace的方法,在fillInStackTrace方法中会调用一个本地方法来填充异常堆栈集合的数据。

这里涉及了JVM执行代码时,遇到异常的方法退出方式。简单的来说就是: JVM在执行过程中,发现了代码中出现异常,且该异常没有在方法体中处理掉,那么他就会退出当前方法的执行,然后返回调用方法中继续抛出这个异常,周而复始,直到有一个方法处理了这个异常,如果一直都没有方法处理该异常就会导致JVM宕掉。

在这个周而复始往调用方抛出异常的过程中,Throwable的fillInStackTrace(int dummy)方法就会详细记录相应堆栈中的数据,从而形成一个完整的堆栈信息表。

参考资料

深入理解Java虚拟机笔记---运行时栈帧结构

转载于:https://my.oschina.net/u/3101282/blog/1846504

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值