
7.2 throws与throw关键字
在异常处理中有两个非常相似的关键字:throws与throw,本节将为读者讲解这两个关键字的使用。
7.2.1 throws关键字
在定义一个方法的时候可以使用throws关键字声明,使用throws声明的方法表示此方法不处理异常,而交给方法的调用处进行处理,throws使用格式如下。
【格式7-2 throws使用格式】

【例7.9】使用throws关键字

因为除法操作有可能出现异常,有可能没有异常,所以在上面代码的div()方法中使用了throws关键字,表示不管是否会有异常,在调用此方法处必须进行异常处理,调用代码如下所示。
【例7.10】处理异常

程序执行结果:

在上面的代码中,不管是否有问题,都要使用try…catch块进行异常的捕获与处理。既然throws是在方法处定义的,那么主方法上也可以使用throws关键字,但是主方法为程序的起点,所以主方法再向上抛异常时,只能将异常抛给JVM进行处理。这就好比一个公司,部门事情处理不了,要上报给经理,经理再解决不了要上报给董事长,到董事长了,也就到头了,那么Java的“头”就是JVM了。
【例7.11】在主方法处使用throws关键字

程序执行结果:

上面的代码在主方法处使用了throws关键字,所以在程序主方法中就可以不再使用try…catch语句进行异常的捕获及处理。
7.2.2 throw关键字
与throws关键字不同的是,可以直接使用throw关键字抛出一个异常。抛出时直接抛出异常类的实例化对象即可。
【例7.12】抛出异常

程序执行结果:

上面的代码并不难以理解,因为异常产生时肯定会由系统产生一个异常类的实例化对象,只是此时异常类的实例化对象是手工产生的而已。
注意
throw不会单独使用。
throw关键字的使用完全符合于异常的处理机制,但是,一般来讲用户都在避免异常的产生,所以不会手工抛出一个新的异常类的实例,而往往会抛出程序中已经产生的异常类实例,这一点在7.2.3节中可以清楚地发现。
说明
提问:为什么要有throw关键字?
在开发中,代码肯定不产生异常才是最好的,那么为什么又要提供有throw,让用户自己产生异常类对象?这样的处理不是很不合理吗?
回答:抛出自己的异常。
实际上Java中的所有异常也都是使用throw抛出的,只不过这部分代码已经被Java隐藏起来,大家感受不到而已。虽然Java本身可以自己抛出异常,但是很多时候如果用户定义了自己的异常类型,那么系统肯定是无法抛出的,这个时候就只能够借助于throw抛出异常,而关于自定义异常,将在本章的后面为读者讲解。
7.2.3 范例——throw与throws的应用
学习了异常的处理格式、throw、throws关键字之后,读者可能会有这样的疑问,这些技术到底该如何应用呢?实际上,在开发中,像try…catch…finally、throw、throws联合使用的情况是比较多的,例如,现在要设计一个相除的方法,但是要求必须打印“计算开始”信息、“计算结束”信息、如果有异常则肯定交给被调用处处理,面对这样的要求就必须把所有的技术点都使用上了,具体代码如下。
【例7.13】综合应用

程序执行结果:

从上面的程序中可以发现,通过合理的搭配程序完成了需要的功能,不管在Math类中的div()方法是否会产生异常都会执行“计算结束”的语句,如果有异常产生则将异常交给调用处进行处理。本程序的具体执行流程如图7-6所示。

图7-6 程序执行流程
上面的代码结构也是在日后的开发中使用得最多的形式,希望读者可以反复体会。
注意
finally语句块的编写要求
finally作为异常的统一出口,所以在此语句块的编写中尽可能不要出现像throw或return这样的语句,这样可以避免不必要的问题出现。
提示
简化异常处理。
以上操作使用的是标准的异常处理结构来进行异常处理的,但是此时用户也可以进行简化方式处理,即:只使用try…finally进行处理。
实例:简化处理

程序执行结果:

上面的程序在div()方法中取消了catch语句,这样当try语句捕获异常之后,会直接执行finally语句内容,而后捕获到的异常将通过div()方法抛出给调用处进行处理。不过从初期学习来讲,不建议这样使用。