java基础篇——异常处理throw与throws的区别

来源:互联网 发布:金牛行情分析软件 编辑:程序博客网 时间:2024/05/22 06:54

在看某软件开发教程的时候发现其异常处理部分讲的糊里糊涂,让我彻底分不清throw和throws的区别及应用范围了。于是,查阅了一些资料,整理成文字,也方便一些同行理解(其中有些内容直接套用了别人的成果,原作者介意的话可以与我联系修改)。


首先来看throw和throws的基本定义:

关键字 含义 throw 抛出一个异常 throws 声明在当前定义的成员方法中所有需要抛出的异常

拿一段完整的代码来说吧:

 void doA(int a) throws Exception1,Exception3{           try{                 ......           }catch(Exception1 e){              throw e;           }catch(Exception2 e){              System.out.println("出错了!");           }           if(a!=b)              throw new  Exception3("自定义异常");}

在上述代码中提到了 Exception1,Exception2,Exception3 三个异常。

首先我们来看throw关键字涉及的两个地方:

第一个是在catch到 Exception1 实例时抛出了这个实例,方法本身并没有处理这个Exception实例。相比较Exception2 ,在catch到Exception2实例时,该方法直接处理了这个Exception实例,并且在控制台输出了字符串。那么这个抛出的Exception实例去哪了呢?它被抛给了调用这个方法的使用者(实质是一个方法),这个调用者可以处理这个Exception实例也可以将这个实例交给调用这个使用者的使用者。因此throw在这里起到了将责任转移的功能,它将一个Exception实例交给了调用这个方法的使用者。
当然如果仅仅是作为一个传递的话代码完全可以使用如下替换,效果是一样的

 void doA(int a) throws Exception1,Exception3{           try{                 ......           }catch(Exception2 e){              System.out.println("出错了!");           }           if(a!=b)              throw new  Exception3("自定义异常");}

是不是发现catch Exception1 没有了?因为在try{……}中如果出现Exception1 而没有被处理,那么它将默认被转移给上层调用者,所以一般使用时若出现throw Exception1实例的情况时,一般还将同时伴有其他功能(就是在throw之前会有其他代码)。

第二个是在if条件下执行的一段代码,你会发现它已经跳出来try{……}catch(Exception ){……}这个组合,原来throw还可以放在任意一个你想要放的地方啊!
那么我们再来看,它做了什么,它抛出了一个刚刚创建好的自定义异常(Exception3实例),然后依然把这个Exception实例抛给了调用者,在if条件成立的前提下。这一次throw成为了创建者,它提醒程序员如果在这里if条件成立了,它就异常了,表面上来看,将这个语句直接替换成
System.out.println("自定义异常");
作为提醒也未尝不可但是还是有区别的。
当然如果调用者会处理这个异常那么异常就会被处理掉,如果调用者不管,那么编译也会通不过,还有一种解决的办法就是再次抛出异常给上层调用者。

综上,我们可以看出throw作用的对象是一个Exception实例,它的作用一部分是为了传递无法处理的异常,一部分可以看做是为了提醒程序员

那么我再来看throws是干什么的,上述代码只有在一个地方出现了throws,在方法声明的时候紧跟着方法名后面,那么为什么后面只有两个Exception呢?
因为 Exception2 已经被该方法处理掉了,所以该方法的调用者不可能再有捕获到Exception2 的可能,所以也就不需要throws了。
那么,如果,我们把
void doA(int a) throws Exception1,Exception3{……}
改成
void doA(int a){……}
之后呢?那么编译都不能通过,因为它提示,下面有throw e;出现,这个地方应该要有throws……因此,只要方法中有异常实例抛出(无论显性或隐性的)并且没有处理,方法声明时就必然有throws

现在再回头看一看开头的定义,是不是一下就明白啦?


另外,有一些朋友可能会疑惑标准异常时我需要throw或者throws吗?
要知道标准异常无论加不加throw和throws它都会抛出异常,重点是如果你要处理它那记得使用try{}catch{}那一对,不然程序就会停在异常处然后就终止了。

0 0