引言

从这篇文章开始,我们学习java中的异常。异常虽然在代码开发过程中占的比重不是很大,但是仍然涉及很多的知识。理解了java中异常的分类和处理机制,能帮助我们写出更优雅的代码。

异常类的层次结构和分类

Throwable

在java中,异常类的顶级父类是Throwable。Throwable是java语言中所有异常类和error类的顶级父类。Throwable的声明如下:

  1. public class Throwable implements Serializable {}

只有Throwable的实例或者它的子类的实例才能被java虚拟机或者throw语句抛出。同样的,只有这个类的实例或者它的子类的实例才能作为catch语句的参数。也就是说,我们在编码过程中使用的try和catch,后面必须是Throwable的实例或者它的子类的实例。
Throwable有两个直接子类,分别是Error和Exception。

Error

《java语言规范》中这样描述Error:Error是普通程序通常不指望能够恢复的所有异常的超类。Error及其所有的子类统统都是错误类。Error一般是我们不应该去捕获的异常,并且在方法的throws语句中,我们也不要求去throw Error的实例或者它的子类的实例。

Exception

Exception是应用程序中想要去catch的异常类。Exception有一个子类是RuntimeException,这个类及其所有子类都是运行时异常,运行时异常和它的所有子类都是非受检异常,除了运行时异常,剩下的就是编译时的受检异常,受检异常需要在方法或者构造方法的throws语句中进行声明。RuntimeException的定义如下:

  1. public class RuntimeException extends Exception {}

所以总结一下就是:
非受检异常类是指运行时异常类(RuntimeException)和错误类(Error)。
受检异常类是除了非受检异常类之外的所有异常类。即受检异常类是Throwable类以及其除了RuntimeException及其子类和Error及其子类的之外的所有子类。

异常的编译时检查

异常的编译时检查是指在编译时对受检异常的检查。看下面的例子:
exception.png
四个方法分别抛出了Throwable、Error、RuntimeException和IOException,IOException是Exception的子类,当调用这四个方法时,Throwable和IOException由于是受检异常,需要在main方法中使用throws语句来显式抛出或者使用try-catch来捕获异常,而Error和RuntimeException不需要。

小结

异常的分类和受检异常的划分是比较简单的,我们只需要记住异常类的层次结构即可。下一篇文章,我们来看异常的运行时处理,这个就相对复杂一些了。