【0012】Error不可以被catch吗?

>>强大,10k+点赞的 SpringBoot 后台管理系统竟然出了详细教程!

【0012】Error不可以被catch吗?

本文将介绍java中的异常与错误,Throwable 类是 Java 语言中所有错误或异常的超类,其子类有Exception和Error。JDK文档有这么一句话:只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出。类似地,只有此类或其子类之一才可以是 catch 子句中的参数类型。也就说Error也是catch子句的参数类型,不只是Exception。由于Error是错误,正常的程序时不应该捕获的,因为这些错误消除后可能再也不会出现,所以我们几乎从来没有看到catch子句中捕获Error的情况,但是Error还是可以被捕获,对于那些说Error不能把捕获的说法,是错误的。

异常是编程中经常使用到的,在模块化开发中,我们也经常定义一些异常,比如Dao层异常、Service层异常,以更好的方式提供给上层程序(Action或者Controller),而不是直接将原始异常抛到上层程序中,这样会破坏分层机构,因为底层抛出的异常是各种各样的,对于上层而言,其实并不关注具体细节,每一层提供一个自定义异常是极其重要的,如果每层都统一抛出一个异常,那么抛出异常的所属的层的上一层只需要捕获这个异常就行了。

本文大纲:

       1Throwable实现原理

       2、自定义异常与错误

       3、案例分析

       4、总结

一、Throwable实现原理

Throwable是一个类,不是一个接口,不要被名字误导。Throwable类中使用StackTraceElement类记录堆栈信息,堆栈信息包括类名、方法名、文件名以及行号。如下图所示:

【0012】Error不可以被catch吗?

Throwable类中有四个私有属性,backtrace主要是记录堆栈中的回调轨迹,detailMessage是产生异常或错误的原因信息,cause代表该异常或错误是由于哪个异常或错误导致,StackTraceElement[]就是具体的堆栈信息。如下图所示:

【0012】Error不可以被catch吗?

【0012】Error不可以被catch吗?

Throwable的构造方法有四个,如下所示(摘自JDK帮助文档):

【0012】Error不可以被catch吗?

Throwable的常用方法,用的最多的就是printStackTrace()方法了,如下所示(摘自JDK帮助文档):

【0012】Error不可以被catch吗?

二、自定义异常与错误

1、自定义异常

异常Exception是Throwable的子类,Exception类内部只提供了四个构造方法,构造方法也是直接调用父类的,没啥特别的。无论是异常或者错误,其核心方法都是由父类提供的。Exception类代码如下(已省略文档注释):

【0012】Error不可以被catch吗?

在日常开发中,有时候我们需要自定义异常,其实很简单,继承Exception类,提供一些构造方法就可以了,比如为Dao层自定义一个异常,如下所示:

【0012】Error不可以被catch吗?

2、自定义错误

毋庸置疑,Error也是Throwable的子类,其实现和Exception几乎一样,也是提供了四个构造方法,没啥其他东西,不展示代码了。那么如何自定义错误呢?其实和自定义异常一样,只不过这次是继承Error类,比如Junit框架中就自定义了一个断言失败错误,如下图所示:

【0012】Error不可以被catch吗?

三、案例

1、我们来catch一下Error

Error也是可以被catch的,在catch子句中声明参数为Throwable或Error,如果声明为Exception则捕获不到异常(这不是废话吗?),看一下下面的单元测试,测试结果显示绿条,表示测试通过,成功捕获Error,你可以自己体验一下捕获Error的感觉,很奇怪哦~

【0012】Error不可以被catch吗?

【0012】Error不可以被catch吗?

2、将堆栈轨迹信息打印到指定的字节流或字符流中

一般情况下,我们程序有异常时,都是先捕获,然后打印堆栈信息,就是调用无参的printStackTrace()方法,但是如果我们要将堆栈信息保存到文件中呢?怎么办?Throwable类中还提供了带参数的两个打印堆栈信息的方法,可以传递一个字节流printStackTrace(PrintStream s)或者字符流printStackTrace(PrintWriters)。接下来我就简单的实现一下将堆栈信息打印到字符流中,然后在打印出来。如果你要写到文件,你将文件字节流对象传递给PrintStream对象就可以了(创建对象时)。

【0012】Error不可以被catch吗?

四、总结

简单总结一下,了解了Throwable类的实现原理后,进行了自定义异常和错误的介绍,这是开发中比较常用的。同时,消除一个误区,Error也是可以被catch的。最后我们也可以将堆栈信息打印到指定的字节流或字符流中,用于我们的特性处理,比如Junit这个框架就是将堆栈信息写到了字符流中,通过另外一种方式呈现出来。

感谢您的阅读,谢谢。


始发于微信公众号: Java框架源码分析