龙空技术网

“全栈2019”Java异常第十六章:认识Throwable

人人都是程序员 238

前言:

现时你们对“java中异常类throwable的子类有”大约比较关切,姐妹们都需要剖析一些“java中异常类throwable的子类有”的相关知识。那么小编也在网摘上收集了一些关于“java中异常类throwable的子类有””的相关资讯,希望看官们能喜欢,小伙伴们一起来学习一下吧!

难度

初级

学习时间

30分钟

适合人群

零基础

开发语言

Java

开发环境JDK v11IntelliJ IDEA v2018.3友情提示本教学属于系列教学,内容具有连贯性,本章使用到的内容之前教学中都有详细讲解。本章内容针对零基础或基础较差的同学比较友好,可能对于有基础的同学来说很简单,希望大家可以根据自己的实际情况选择继续看完或等待看下一篇文章。谢谢大家的谅解!1.异常体系

在Java异常这个大家族中,Throwable是这个异常家族中的老大,它下面有两个靠谱老弟,一个叫“Error”,一个叫“Exception”。Error老弟负责错误部门,Exception老弟负责异常部门,它们各司其职。我给它们做了一个结构图:

Exception我们已经不陌生了,前面文章都和Exception有关,Error我们比较陌生一点,下一章我们就着重讲解它。

接下来,我们来一起认识Throwable这个父类。

2.Throwable类是Java语言中所有错误和异常的父类

标题中的错误指的是Error及其子类。

标题中的异常指的是Exception及其子类。

Throwable类它有两个直接子类,一个是Error,还有一个是Exception:

Error继承自Throwable类

Exception继承自Throwable类

我们知道,一类相同的事物抽取出来的共同特性都在父类中,所以Throwable这个类里面存在的成员必定是Error和Exception共同拥有的特性。至于共性部分我们下面有讲解,请大家慢慢看。

3.catch参数类型必须是Throwable类或其子类

我们知道当我们遇到异常时,可以使用try-catch来处理异常,前面也在《“全栈2019”Java异常第二章:如何处理异常?》一章中学习过:

但是大家知道吗?catch子句的参数类型只能是Throwable类或其子类。例如,Error和Exception都可以:

catch参数类型为Error类或其子类

catch参数类型为Exception类或其子类

4.只有Throwable类或其子类对象才能被throw抛出

throw关键字前面我们在《“全栈2019”Java异常第八章:throw关键字详解》一章中学习过。throw关键字后面跟的是Throwable类或其子类对象。也就是说,我们可以抛出Throwable对象:

也可以抛出Throwable子类对象:

抛出Error类及其子类

抛出Exception类及其子类

5.已检查的异常

什么是已检查的异常?

出于编译时检查异常的目的,Throwable和Throwable的任何子类(除Error和RuntimeException的子类)都被视为已检查的异常。

不明白没关系,我们来分词解释+举例说明。

第一句,出于编译时检查异常的目的:

通过该句我们可以知道的是,已检查的异常是在编译时要被检查的。

检查是什么意思?

检查的意思就是看你对这些已检查的异常有没有进行try-catch或throws处理。

已检查的异常到底是哪些请看下面第二句的分析。

第二句,Throwable和Throwable的任何子类(除Error和RuntimeException的子类)都被视为已检查的异常:

上图中红色部分都是已检查的异常。

已检查的异常例子来一个吧。这个就很多了,前面我们也写过不少,所以呢,这里我们就举一个读取文本文件的例子。

演示:

请捕获已检查的异常。

请观察程序代码和结果。

代码:

Main类:

结果:

程序运行结果是对的,但不是我们关注的重点,我们关注的重点是捕获已检查的异常:

这里我们捕获了两个已检查的异常,按照已检查的异常定义,IOException是Exception的子类,所以IOException是已检查的异常;而FileNotFoundException是IOException的子类,故FileNotFoundException也是已检查的异常。

那么已检查的异常有什么特别之处吗?

已检查的异常特别之处就是在于它们被产生时,需要你try-catch或throws将其处理掉,如果你不处理那么在程序就不会编译通过。

从另外一个角度来讲,程序发生已检查的异常的目的在于提醒开发人员将其反馈给用户,怎么说?

你比如说,上述程序是读取文本文件,首先我们会让用户输入一个文件的路径,然后我们程序就会去读取这个文件,假如文件不存时,就会发生FileNotFoundException异常,这个时候就应该提示用户,告诉说“对不起,您输入的文件路径不存在,请重新输入”。这样友好的提醒也是已检查异常发生时强制我们try-catch或throws处理的一个原因。希望大家可以好好理解已检查的异常,开发出更加优秀的程序软件。

6.打印堆栈跟踪信息

打印堆栈跟踪信息,这个我们不陌生,它就是父类Throwable的printStackTrace()方法:

public void printStackTrace()

printStackTrace()方法在《“全栈2019”Java异常第十三章:访问异常堆栈跟踪信息》一章中,我们也进行过学习。下面演示一下。

演示:

请使用printStackTrace()方法打印堆栈跟踪信息。

请观察程序代码和结果。

代码:

Main类:

结果:

程序非常简单,我们使用“1除以0”制造了一个异常,然后将其捕获,在catch代码块中通过调用printStackTrace()方法打印堆栈跟踪信息。结果中有三部分:

第一部分,“java.lang.ArithmeticException:” :

该部分是异常类型。

第二部分,“/ by zero”:

该部分是异常信息。

第三部分,“at main.Main.main(Main.java:13)”:

该部分是发生异常的地方。

最后,printStackTrace()方法还有两个重载方法:

void printStackTrace​(PrintStream s)void printStackTrace​(PrintWriter s)

其中printStackTrace​(PrintWriter s)方法应用场景在《“全栈2019”Java异常第十四章:将异常输出到文本文件中》一章中我们学习过。

7.异常链

说起异常链,我们再熟悉不过了,因为在上一章《“全栈2019”Java异常第十五章:异常链详解》中我们刚刚学习过什么是异常链。

这里呢,就简单演示一下,详情请大家点击上面刚刚写的文章链接进行学习。

演示:

请构造一个异常链。

请观察程序代码和结果。

代码:

Main类:

结果:

程序非常简单,前面我们也写过。这里直接说下异常链的核心:

捕获一个异常后,抛出新异常并且保存原异常信息。

在本例中,捕获一个异常指的是IOException:

抛出新异常指的是ClassNotFoundException:

保存原异常信息指的是构造ClassNotFoundException异常对象时将IOException对象e传入进构造方法参数中:

好了,异常链的简单程序就讲解完毕,想了解更多相关内容请点击阅读《“全栈2019”Java异常第十五章:异常链详解》一文。

8.使用initCause​(Throwable cause)方法覆盖之前的原因(Throwable对象)

我们异常链还有一种构造方式:

public Throwable initCause​(Throwable cause)

通过initCause​(Throwable cause)方法我们也可以构造出异常链来。下面通过例子来演示给大家看。

将上一小节中的例子通过initCause​(Throwable cause)方法改写:

运行程序,执行结果:

程序发生了错误:

文字版:

Exception in thread "main" java.lang.IllegalStateException: Can't overwrite cause with java.io.IOException

at java.base/java.lang.Throwable.initCause(Throwable.java:462)

at main.Main.a(Main.java:35)

at main.Main.main(Main.java:15)

Caused by: java.lang.ClassNotFoundException: 使用initCause()方法构造异常链

at main.Main.a(Main.java:33)

... 1 more

程序错误的主要原因是:无法用java.io.IOException覆盖原因。

我们到底是哪一步改写错误了呢,来看程序代码:

错误的产生就在这一行,为什么会产生错误呢?进一步来看:

这是initCause​(Throwable cause)方法源码,从源码中我们可以看到这样一行代码:

这个if语句里面就是产生上述错误的源头。

这个方法体内部代码说明initCause​(Throwable cause)方法仅仅是用来覆盖之前的原因(Throwable对象)。而且希望的是你能够捕获低级异常抛出高级异常,抛出高级异常的同时可以使用initCause​(Throwable cause)方法覆盖掉原先的原因(Throwable对象)。

具体的还是举例来说明一下吧。

演示:

请使用initCause​(Throwable cause)方法来覆盖之前的低级原因(Throwable对象)。

请观察程序代码及结果。

代码:

Main类:

结果:

程序代码没有任何问题,结果也是符合预期的。

其中我们捕获的低级异常FileNotFoundException是IOException的子类:

我们抛出的新异常(高级异常)IOException是FileNotFoundException的父类:

所谓低级异常和高级异常只不过是它们的关系是父子关系。就像FileNotFoundException和IOException一样。

这就是initCause​(Throwable cause)方法正确的使用方式。

9.使用getCause()方法获取原因(Throwable对象)

getCause()方法原型如下:

public Throwable getCause()

getCause()方法用于获取原因(Throwable对象)。接下来,我们来通过一个例子来感受一下。

还是上一小节的例子,我们来将其改写一下:

运行程序,执行结果:

先不着急看结果,我们先来看看改写哪两个地方:

我们将两个方法里面的catch代码块进行改写。

再来看看程序执行结果:

java.io.FileNotFoundException

at main.Main.a(Main.java:33)

at main.Main.main(Main.java:16)

这个结果就是原因(Throwable对象)的堆栈跟踪信息。

getCause()方法非常简单,日常开发中用的频率不高,但是希望大家能够知道它是干什么的就够了。

10.使用getMessage()方法获取Throwable详细信息

getMessage()方法原型:

public String getMessage()

getMessage()方法主要是用来获取Throwable详细信息的,它返回一个字符串类型,可以为空。

接下来,我们来演示一下。

演示:

请使用getMessage()方法来获取Throwable详细信息。

请观察程序代码和结果。

代码:

Main类:

结果:

从程序执行结果来看,我们获取到的部分好像和下面这部分很像:

是不是一摸一样?

是的,那么请问它前面的是这么来的呢?

它前面是通过e.getClass().getName()方法获取的。

执行结果:

所以将其整合在一起就是:

执行结果:

其实我们的Throwable的toString()方法就是这样写的:

好了,我们通过Throwable的getMessage()方法来获取Throwab详细详细讲解到这,说明一下,这个详细信息其实就是对这个Throwable对象的解释说明。getMessage()方法在实际开发中使用的频率还是蛮高的,这个大家会用就行。

Throwable讲解到此就先告一段落了,或许我讲解的不好,希望大家能够在评论区留言指出不好的地方,未来我会加以改正,会越写越好的技术文章来回馈大家。

总结Throwable类是Java语言中所有错误和异常的父类。catch参数类型必须是Throwable类或其子类。只有Throwable类或其子类对象才能被throw抛出。出于编译时检查异常的目的,Throwable和Throwable的任何子类(除Error和RuntimeException的子类)都被视为已检查的异常。使用printStackTrace()方法打印堆栈跟踪信息。捕获一个异常后抛出另一个异常,并且把原始异常信息保存下来,这被称为异常链。initCause​(Throwable cause)方法仅仅是用来覆盖之前的原因(Throwable对象)。而且希望的是你能够捕获低级异常抛出高级异常,抛出高级异常的同时可以使用initCause​(Throwable cause)方法覆盖掉原先的原因(Throwable对象)。使用getCause()方法获取原因(Throwable对象)。使用getMessage()方法获取Throwable详细信息。

至此,Java中Throwable相关内容讲解先告一段落,更多内容请持续关注。

答疑

如果大家有问题或想了解更多前沿技术,请在下方留言或评论,我会为大家解答。

上一章

“全栈2019”Java异常第十五章:异常链详解

下一章

“全栈2019”Java异常第十七章:Error详解

学习小组

加入同步学习小组,共同交流与进步。

方式一:关注头条号Gorhaf,私信“Java学习小组”。方式二:关注公众号Gorhaf,回复“Java学习小组”。全栈工程师学习计划

关注我们,加入“全栈工程师学习计划”。

版权声明

原创不易,未经允许不得转载!

标签: #java中异常类throwable的子类有