7.2throws 和 throw 关键字
在异常处理中有两个非常相似的关键字:throws和throw,本节将向读者讲解这两个关键字的用法。
7.2.1 throws 关键字
定义方法时,可以使用 throws 关键字进行声明。使用 throws 声明的方法表示此方法不处理异常,而是将异常留给方法调用者处理。throws 的格式如下。
【格式7-2 投掷使用格式】
[例 7.9] 使用 throws 关键字
因为除法操作可能会有异常,也可能不会有异常,所以上述代码中 div() 方法中使用了 throws 关键字,表示不管是否会有异常,调用此方法时都必须进行异常处理。调用代码如下。
[例 7.10] 处理异常
程序执行结果:
上述代码中,不管有没有问题,都必须使用try...catch块来捕获并处理异常。由于throws是定义在方法处,所以throws关键字也可以用在main方法上,但是main方法是程序的起点,所以当main方法向上抛出异常时,只能将异常抛给JVM来处理。这就好比一个公司,如果某个部门处理不了某件事,就要上报经理,经理解决不了,就要上报董事长。到了董事长那里就是末日了,所以Java的“头”就是JVM。
[例 7.11] 在 main 方法中使用 throws 关键字
程序执行结果:
上述代码在main方法中使用了throws关键字,因此在程序的main方法中不需要再使用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()方法抛给调用处进行处理。不过,对于初学的同学,不建议这样做。