Java异常体系详解
保留所有版权,请引用而不是转载本文(原文地址 https://yeecode.top/blog/43/ )。
“异常”代表程序运行中遇到了意料之外的事情,为了表征异常,Java标准库中内建了一些通用的异常。今天我们就介绍Java中的异常体系。
Java中的异常类均以Throwable为父类,而Throwable又派生出Error类和Exception类这两大子类。
- Error类及其子类,代表了JVM自身的异常。这一类异常发生时,无法通过程序来修正。最可靠的方式就是尽快地停止JVM的运行。
- Exception类及其子类,代表程序运行中发生了意料之外的事情。这些意外的事情可以被Java异常处理机制处理。而Exception类及其子类又可以划分为两大类:
- RuntimeException及其子类:这一类异常其实是程序设计的错误,通过修正程序设计是可以避免的。例如,数组越界异常、数值异常等。
- 非RuntimeException及其子类:这一类异常的发生通常由外部因素导致,是不可预知和避免的。例如,IO异常、类型寻找异常等。
在遇到复杂的类间关系时,绘制它们的UML类图是理清它们关系的非常好的手段。很多时候,在绘制UML类图的过程中,你就会对它们之间的关系豁然开朗。Throwable及其子类的继承关系可以用下面的类图表示。
在所有异常中,Error及其子类代表JVM出现异常,无法通过软件修复;RuntimeException及其子类是程序设计的错误,可以在编写程序时避免。以上这两大类异常称为免检异常,即不需要对这两类异常进行强制的检查。而除去上面两类异常的其他异常,它们的发生与外部环境有关,被称为必检异常。在编写程序时必须用try、catch语句将其包围起来。
对于Throwable对象,其主要的成员变量有detailMessage
和cause
:
detailMessage
为一个String,用来存储异常的详细信息;cause
为另一个Throwable对象,用来存储异常引发原因。这是因为一个异常发生时,通常引发的的上级程序也发生异常,从而导致一连串的异常产生,叫作异常链。一个异常的cause属性可以指向引发它的下级异常,从而将整个异常链保存下来,如图所示。
在进行软件系统架构时,创建一套合理的异常框架供项目使用是十分必要的。这一点可以参照MyBatis的异常设计,例如在MyBatis中,便设计了如下的一套异常体系。
这些异常类中除去RuntimeSqlException类外均为PersistenceException的子类。
关于MyBatis的异常设计的具体架构思路和源码分析,大家可以参照《通用源码阅读指导书》。这是一本以MyBatis的源码为实例讲述源码阅读方法的书籍,非常推荐。
多读读源码,进步会很大。
可以访问个人知乎阅读更多文章:易哥(https://www.zhihu.com/people/yeecode),欢迎关注。