1、异常概述和捕捉异常

异常概述

在程序运行时可能出现得一些错误称为异常,异常是在一个程序执行时期发生的事件,它中断了正在执行的程序的正常指令流。异常有很多种,如空指针异常、算术异常、类型转换异常、数组下标越界异常、未找到相应类异常……
image.png
除了异常,更加严重的问题是错误(error),是不能用代码可以解决的错误了:
image.png

捕捉异常

可以通过使用try-catch-finally语句块捕捉异常,try语句块存放的是可能发生异常的语句,catch语句块在try之后,用来激活被捕捉的异常,finally是异常处理结构的最后执行部分(可以没有),无论try语句块中的代码如何退出,都将执行finally语句块。当try语句块中的语句发生异常时,程序就会调转到catch代码块中,执行完catch代码块中的代码后,将继续执行catch代码块的其它代码,而不会执行代码块中发生异常语句后面的代码。
image.png
image.png
image.png

image.png
注意:Exception是try代码块传递给catch代码块的变量类型,e是变量名。catch代码块中语句“e.printStackTrace()”用于打印异常的类型、性质及出现在程序中的位置。finally语句块在下面四种情况下不会被执行:在finally语句块中发生了异常;在前面的代码中使用了System.exit()语句退出程序;程序所在的线程死亡;关闭CPU。

2、在方法中抛出异常

如果某个方法可能会发生异常,但不想在当前方法中处理这个异常,则可以使用throws、throw关键字在方法中抛出。

使用throws关键字抛出异常

throws关键字通常被应用在声明方法时,用来指定方法可能抛出的异常,多个异常可使用逗号隔开。
image.png
image.png
调用了throws声明的方法之后,那么不管操作是否出现异常,都必须使用try…catch语句进行异常处理。 主方法使用throws后,那么这个异常就将交给JVM进行处理,而后结束程序用。

使用throw关键字抛出异常

throw关键字通常用于方法体中,并且抛出一个异常对象。程序执行到throw语句时立刻终止,它后面的语句都不执行,如果要捕获throw抛出的异常,则必须使用try-catch语句块。
image.png

throw 和 throws的区别

throw:指的是在方法体中人为抛出一个异常类对象,这个对象可以是自己实例化,或者是已经存在的。
throws: 指的是在方法的声明上使用,表示此方法在调用时必须处理异常。

throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常。两者都是消极处理异常的方式(这里的消极并不是说这种方式不好),只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的处理异常由函数的上层调用处理。

3、自定义异常

有些异常时人们自己认为的异常但是API中是没有的,比如:一场由人类参加的跑步比赛,结果有一只猴子参加了,这种异常在API中是没有的,要想捕捉到这种异常就只有自定义这是一种异常了。在程序中使用自定义异常,大体分为以下几个步骤:
创建自定义异常;
在方法中通过throw关键字抛出异常对象;
如果在当前抛出异常的方法中处理异常,可以使用try-catch语句块捕获并处理,否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作;
在出现异常方法的调用者中捕获并处理异常。

image.png
image.png
image.png

4、检查型异常与非检查型异常

最简单的判断点有两个:
1.继承自Runtime Exception或 Error 的是非检查型异常,而继承自 Exception 的则是检查型异(当然,Runtime Exception 本身也是 Exception 的子类)。
2.对非检查型类异常可以不用捕获,而检查型异常则必须用try语句块进行处理或者把异常交给上级方法处理总之就是必须写代码处理它。

Java 的异常结构如下图。其中直接继承 Exception 的异常,必须捕获,属于检查型异常。其他的可以不用捕获,属于非检查型异常。
image.png