抽时间整理了下java中异常与return,以前这块总是弄混淆,觉得还是写下来慢慢整理比较好。由于水平有限,仅供参考。废话不多说,直接上代码。
下面是两个方法:
1 public static int throwReturn(){
2 int ret = 0;
3 try{
4 ret = 10/0 ;
5 ret++;
6 return ret;
7 }catch(Exception e){
8 System.out.println("catch block " + e.getMessage());
9 //ret++;
10 return ret;
11 }finally{
12 System.out.println("finally block invoked!!!");
13 ret++;
14 System.out.println("finally block invoked, ret is " + ret);
15 }
16
17 }
1 public static int finallyReturn(){
2 int ret = 0;
3 try{
4 ret = 10/0 ;
5 ret++;
6 return ret;
7 }catch(Exception e){
8 System.out.println("catch block " + e.getMessage());
9 //ret++;
10 return ret;
11 }finally{
12 System.out.println("finally block invoked!!!");
13 ret++;
14 System.out.println("finally block invoked, ret is " + ret);
15 return ret;
16 }
17
18 }
然后在主方法中分别调用两个方法:
1 public static void main(String args[]){
2 System.out.println("throwReturn:" + throwReturn());
3 //System.out.println("finallyReturn:" + finallyReturn());
4 }
第一个方法输出结果:
catch block / by zero
finally block invoked!!!
finally block invoked, ret is 1
throwReturn:0
throwRetrun方法返回的结果并不是我预想的1,而是0。
个人分析:
- 程序执行到throwReturn方法的第4行时由于除0而出错,程序进入catch块,首先会执行打印输出:catch block / by zero
- 接下来会执行catch块的return ret语句,碰到return语句方法会返回退出,而finally语句又是必须执行的,此时程序会将return的结果值暂存起来,继续执行finally块。
- 进入finally块后会输出:finally block invoked!!! 和finally block invoked, ret is 1
- finally块执行完成后程序会回到return处,并返回当时暂存的值
第二个方法的输出结果:
catch block / by zero
finally block invoked!!!
finally block invoked, ret is 1
finallyReturn:1
哎,这次的输出结果是1了。
仔细比较两个方法发现第二个方法,在finally语句中多了一个return ret;程序的执行过程同上面基本上是一样的,只是在最终执行finally代码块是碰到了return语句,此时程序就直接将ret的值返回了,而此时ret的值是1,最后输出:finallyReturn:1
接下来我们再看2个方法:
1 public static int throwException() throws Exception{
2 int ret = 0;
3 try{
4 ret = 10/0 ;
5 System.out.println("ret:" + ret);
6 return ret;
7 }catch(Exception e){
8 System.out.println("catch block " + e.getMessage());
9 throw e;
10 }finally{
11 System.out.println("finally block invoked!!!");
12 ret++;
13 System.out.println("finally block invoked, ret is " + ret);
14 }
15
16 }
1 public static int finallyThrowException() throws Exception{
2 int ret = 0;
3 try{
4 ret = 10/0 ;
5 System.out.println("ret:" + ret);
6 return ret;
7 }catch(Exception e){
8 System.out.println("catch block " + e.getMessage());
9 throw e;
10 }finally{
11 System.out.println("finally block invoked!!!");
12 ret++;
13 System.out.println("finally block invoked, ret is " + ret);
14 return ret;
15 }
16
17 }
然后在主方法中分别调用两个上面方法:
1 public static void main(String args[]){
2 try {
3 System.out.println("throwException:" + throwException());
4 } catch (Exception e) {
5 System.out.println("捕获到throwException方法抛出的异常," + e.getMessage());
6 }
7
8 /*try {
9 System.out.println("finallyThrowException:" + finallyThrowException());
10 } catch (Exception e) {
11 System.out.println("捕获到finallyThrowException方法抛出的异常," + e.getMessage());
12 }*/
13 }
第一个方法输出结果:
catch block / by zero
finally block invoked!!!
finally block invoked, ret is 1
捕获到throwException方法抛出的异常,/ by zero
个人分析:
- 在throwException方法执行到第4行时,因为除0操作抛出异常,程序进入catch块,首先执行打印输出:catch block / by zero
- 接下来会执行catch块的throw e语句,向上抛出异常,而finally语句又是必须执行的,此时程序会先执行finally块。
- 进入finally块后会输出:finally block invoked!!! 和finally block invoked, ret is 1
- finally块执行完成后程序会回到catch块throw处,将捕获的异常向上抛出
- 在main方法中会捕获到throwException方法抛出的异常而进入catch块,所以会输出:捕获到throwException方法抛出的异常,/ by zero
第二个方法的输出结果:
catch block / by zero
finally block invoked!!!
finally block invoked, ret is 1
finallyThrowException:1
观察输出结果会发现,主方法并没有捕获到finallyThrowException方法调用时的异常(catch块的打印没有执行)。
这两个方法的主要区别也是在于:在finallyThrowException方法的finally块中多出了return ret语句。调用finallyThrowException方法的执行过程同调用throwException方法基本一致。
- 在finallyThrowException方法执行时,因为除0操作抛出异常,程序进入catch块,首先执行打印输出:catch block / by zero
- 接下来会执行catch块的throw e语句,向上抛出异常,而finally语句又是必须执行的,此时程序会先执行finally块。
- 进入finally块后会输出:finally block invoked!!! 和finally block invoked, ret is 1
- finally块执行到return ret时,该方法直接返回了ret的值,
- 在main方法中得到finallyThrowException的返回值后输出:finallyThrowException:1
从finallyThrowException方法执行结果可以看出方法执行时的异常被丢失了
最后再来看一个小例子
1 public static void finallyWork(){
2 int count = 0;
3 while(true){
4 try{
5 if(count++ == 0){
6 throw new Exception("my error");
7 }
8 System.out.println("invoked ...");
9 }catch(Exception e){
10 System.out.println("catched exception:" + e.getMessage());
11 }finally{
12 System.out.println("finally block invoked!!!");
13 if(count == 2){
14 break;
15 }
16 }
17 }
18 }
这个小例子的主要思路是当java中的异常不允许我们回到异常抛出的地点时,我们可以将try块放到循环里,这样程序就又可以回到异常的抛出点了,可以同时设置一个计数器,当累积尝试一定的次数后程序就退出。
ok,就说这么多了,下面附上完整代码:
package tt;
public class FinallyWorks {
/**
* @param args
*/
public static void main(String[] args) {
//finallyWork();
/*
*<output begin>
* catch block / by zero
* finally block invoked!!!
* finally block invoked, ret is 1
* throwReturn:0
*</output end>
*从输出结果中可以看出程序在int temp = 10/0;这一行抛出异常,直接进入catch块,首先输出打印catch block...,继续往下执行时碰到return语句,由于程序
*存在finally语句,在程序返回之前需要执行finally语句。那么此时程序会将return的结果值暂时存起来,继续执行finally,从输出上可以看出finally执行后ret
*的值变为了1,而整个方法最终的返回结果是0,说明return的是之前暂存的值。
* */
//System.out.println("throwReturn:" + throwReturn());
/*
* <output begin>
* catch block / by zero
* finally block invoked!!!
* finally block invoked, ret is 1
* finallyReturn:1
*</output end>
*从输出结果中可以看出程序在int temp = 10/0;这一行抛出异常,直接进入catch块,首先输出打印catch block...,继续往下执行时碰到return语句,由于程序
*存在finally语句,在程序返回之前需要执行finally语句。那么此时程序会将return的结果值暂时存起来,继续执行finally,从输出上可以看出finally执行后ret
*的值变为了1,有在finally块中碰到了return语句,方法就直接返回了,所以方法结果返回了1。
* */
//System.out.println("finallyReturn:" + finallyReturn());
/*
*<output begin>
* catch block / by zero
* finally block invoked!!!
* finally block invoked, ret is 1
* 捕获到throwException方法抛出的异常,/ by zero
*</output end>
*从输出结果中可以看出在调用throwException方法是出现异常,程序进入该方法的catch块中,输出:catch block / by zero
*由于存在finally,程序会先执行完finally语句输出:finally block invoked!!! 和 finally block invoked, ret is 1
*然后将捕获到的异常抛向上层。上层的main方法catch到这个异常之后会输出:捕获到throwException方法抛出的异常,/ by zero
*《注意throwException:那句打印是不会输出的》
* */
/*try {
System.out.println("throwException:" + throwException());
} catch (Exception e) {
System.out.println("捕获到throwException方法抛出的异常," + e.getMessage());
}*/
/*
*<output begin>
* catch block / by zero
* finally block invoked!!!
* finally block invoked, ret is 1
* finallyThrowException:1
*</output end>
*从输出结果中可以看出在调用finallyThrowException方法是出现异常,程序进入该方法的catch块中,输出:catch block / by zero
*由于存在finally,程序会先执行完finally语句输出:finally block invoked!!! 和 finally block invoked, ret is 1
*之后程序执行到finally块中return语句,直接返回了ret的值,主方法接受到这个返回值后输出:finallyThrowException:1
*《注意主方法中catch块代码并没有被执行,这就说明了finallyThrowException方法中异常被丢失了》
* */
try {
System.out.println("finallyThrowException:" + finallyThrowException());
} catch (Exception e) {
System.out.println("捕获到finallyThrowException方法抛出的异常," + e.getMessage());
}
}
public static int throwException() throws Exception{
int ret = 0;
try{
ret = 10/0 ;
System.out.println("ret:" + ret);
return ret;
}catch(Exception e){
System.out.println("catch block " + e.getMessage());
throw e;
}finally{
System.out.println("finally block invoked!!!");
ret++;
System.out.println("finally block invoked, ret is " + ret);
}
}
public static int finallyThrowException() throws Exception{
int ret = 0;
try{
ret = 10/0 ;
System.out.println("ret:" + ret);
return ret;
}catch(Exception e){
System.out.println("catch block " + e.getMessage());
throw e;
}finally{
System.out.println("finally block invoked!!!");
ret++;
System.out.println("finally block invoked, ret is " + ret);
return ret;
}
}
public static int throwReturn(){
int ret = 0;
try{
ret = 10/0 ;
ret++;
return ret;
}catch(Exception e){
System.out.println("catch block " + e.getMessage());
//ret++;
return ret;
}finally{
System.out.println("finally block invoked!!!");
ret++;
System.out.println("finally block invoked, ret is " + ret);
}
}
public static int finallyReturn(){
int ret = 0;
try{
ret = 10/0 ;
ret++;
return ret;
}catch(Exception e){
System.out.println("catch block " + e.getMessage());
//ret++;
return ret;
}finally{
System.out.println("finally block invoked!!!");
ret++;
System.out.println("finally block invoked, ret is " + ret);
return ret;
}
}
/**
* 当java中的异常不允许我们回到异常抛出的地点时,我们可以将try块放到循环里,
* 这样程序就又可以回到异常的抛出点了,可以同时设置一个计数器,
* 当累积尝试一定的次数后程序就退出。
*/
public static void finallyWork(){
int count = 0;
while(true){
try{
if(count++ == 0){
throw new Exception("my error");
}
System.out.println("invoked ...");
}catch(Exception e){
System.out.println("catched exception:" + e.getMessage());
}finally{
System.out.println("finally block invoked!!!");
if(count == 2){
break;
}
}
}
}
}
|