Java中允许对异常进行再次抛出,以提交给上一层进行处理,最为明显的例子为Java的常规异常。
常规异常:有Java所定义的异常,不需要异常声明,在未被try-catch的情况下,会被默认上报到main()方法。
Example:
public class TestException {
TestException(int i) throws ExceptionA,ExceptionB{
int a[]={0,}; a[1]=1;
}
}
当从main()方法中调用TestException类的构造函数的时候,会得到以下的异常提示,从中可以看出异常的冒泡机制(这是一个栈信息)。
异常的冒泡上传机制:当一个异常对象产生了以后,其会按照调用层次(一般是方法的调用层次)进行冒泡,直到被try-catch处理,或上报至main()方法,有编译器进行提示。
Example:
firstThrow()提示错误的原因为, firstThrow()的函数声明中包括了MyException的异常声明,而secondThrow()中调用了firstThrow()却未对可能抛出的异常对象提供任何处理方案,这是编译器所不能允许发生的事情。(这也是为了保证底层异常对象在冒泡过程中,能得到合适的处理和重视!)
注意此截图中,MyEclipse提供了两种方式帮助fix这个程序,这两种方式常用的异常应对手段:
1、本方法不给予处理,将异常上报给上一层。
1 public class TestExceptionChain {
2 void firstThrow() throws MyException
3 {
4 print("Oringinally creat a MyException and throw it out");
5 throw new MyException();
6
7 }
8 void secondThrow() throws MyException
9 {
10 firstThrow();
11 }
12 TestExceptionChain() throws MyException{
13 secondThrow();
14 }
15 }
1 public static void main(String[] args) {
2 try{
3
4 TestExceptionChain testExceptionChain=new TestExceptionChain();
5 }
6 catch(MyException e)
7 {
8 e.printStackTrace();
9 print("Catch a my exception!");
10 }
11
12 }
控制台的输出为:
从异常栈的记录信息可以发现,与代码相对应的异常抛出机制和次序:
firstThrow()产生MyException对象->异常冒泡至调用其的secondThrow()->异常冒泡至调用secondThrow()的TestExceptionChain的构造方法->冒泡至printtry的main()方法。
注意到:异常对象一直被抛出,直至在printtry的mian()方法中被try-catch捕获!
2、try-catch方式,捕捉上报的异常,而后进行相应处理或抛出另一异常。
2、1捕获异常后,进行相应处理。
Example:
1 public class TestExceptionChain {
2 void firstThrow() throws MyException
3 {
4 print("Oringinally creat a MyException and throw it out");
5 throw new MyException();
6 }
7 void secondThrow()
8 {
9 try
10 {
11 firstThrow();
12 }
13 catch (MyException e)
14 {
15 print("I have just caught a MyExcepton,but i want to do nothing for it");
16 e.printStackTrace();
17 }
18 }
19 TestExceptionChain(){
20 secondThrow();
21 }
从图中可以发现,异常在secondThrow() 中被try-catch模块捕获,并执行了相应的处理操作,所以其函数声明中无需添加异常声明,异常不会被上报。
故mian()方法被改写成了以下的代码:
1 TestExceptionChain testExceptionChain=new TestExceptionChain();
注意此处异常栈的信息,表示的是异常产生的层次信息,并非异常信息的上报层次,因为其已经在secondThorow()中被捕获处理。
2.2 捕获异常后,抛出另一个异常。
Example:
1 public class TestExceptionChain {
2 void firstThrow() throws MyException
3 {
4 print("Oringinally creat a MyException and throw it out");
5 throw new MyException();
6 }
7 void secondThrow() throws YouException
8 {
9 try
10 {
11 firstThrow();
12 }
13 catch (MyException e)
14 {
15 print("I have just caught a MyExcepton,but i want to create a YouException and throw it out");
16 e.printStackTrace();
17 throw new YouException();
18 }
19 }
20 TestExceptionChain() throws YouException{
21 secondThrow();
22 }
23 }
24 class MyException extends Exception{}
25 class YouException extends Exception{}
从异常栈信息中可以发现,新抛出的YouException对象是从secondThrow()中开始的。
*Java中还提供了fillInStackTrace()方法,用于对捕获的异常的栈信息进行重写。
Example:
1 try{
2
3 TestExceptionChain testExceptionChain=new TestExceptionChain();
4 }
5 catch(YouException e)
6 {
7 print("Catch a YouException!");
8 e.fillInStackTrace();
9 e.printStackTrace();
10
11 }
由于使用了fillInstack()方法,关于YouException的异常信息被重写,从其被从写处重新记录!
|