`
kakajw
  • 浏览: 263291 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

try catch finally 和 return 之间的顺序纠葛

 
阅读更多

 

return语句在try-catch-finally中的执行顺序

 

一般情况下:

public class TryCatchReturn {	

	public static void main(String[] args) {		
		TryCatchReturn tcr = new TryCatchReturn();
		System.out.println("tcr.test(): "+tcr.test());
	}
	
	public int test(){
		int a = 0;
		
		try{
			System.out.println("a: "+a);
			a = 110;
		}catch(Exception e){
			a = a+3;			
		}finally{
			a ++;
			System.out.println("finally a: "+a);
		}
		return a;     
	}	
}

执行结果:

a: 0
finally a: 111
tcr.test(): 111

 

 

1.首先测试3个块的return的优先级

 

public class TryCatchReturn {	

	public static void main(String[] args) {		
		TryCatchReturn tcr = new TryCatchReturn();
		System.out.println("tcr.test(): "+tcr.test());
	}
	
	public int test(){
		int a = 0;
		
		try{
			System.out.println("a: "+a);
			a = 110;
			return a;
		}catch(Exception e){
			a = a+3;
			return a;
			
		}finally{                 //警告: finally block does not complete normally 
			a ++;
			System.out.println("finally a: "+a);
			return a;			
		}
		//return a;                                                //编译报错,不被执行! 
	}	
}

执行结果:

a: 0
finally a: 111
tcr.test(): 111

 

可知test()方法最后是从finally模块的return语句返回的;

 

结论:

1.finally 模块总是会得到执行,且finally模块的return 也总会被执行,而此时try模块的return可以被认为是没有被执行;

2.不推荐在finally模块内return;

 

 

 

2.测试finally块无return时的返回顺序;

public class TryCatchReturn {	

	public static void main(String[] args) {		
		TryCatchReturn tcr = new TryCatchReturn();
		System.out.println("tcr.test(): "+tcr.test());
	}
	
	public int test(){
		int a = 0;
		
		try{
			System.out.println("a: "+a);
			a = 110;
			return a;
		}catch(Exception e){
			a = a+3;
			return a;  
		}finally{
			a ++;
			System.out.println("finally a: "+a);	
		}     
	}	
}

执行结果:

a: 0
finally a: 111
tcr.test(): 110

 

test()方法中,try模块的return语句先于finally模块执行,但return并不立即返回,而是执行后,将把返回结果放置进函数栈中,待finally模块执行完后,又返回至try模块的return语句,退出方法,完成执行。因此,对于此种情况,可以认为try模块的return语句先于finally模块执行,但是方法最终还是从return语句返回退出的。

 

结论:

1. 当try或catch块中有return语句时,finally模块中的语句仍会执行;

2. 当try或catch模块有return语句,若finally模块中无return时,try或catch模块的return返回值在finally模执行前确定的,且return语句先于finally模块执行;

3.当return在try-catch-finally语句之后时,finally模块是在return前执行的;(如首例子所示)

 

3.测试catch模块介入时return的返回顺序(finally无return);

public class TryCatchReturn {	

	public static void main(String[] args) {		
		TryCatchReturn tcr = new TryCatchReturn();
		System.out.println("tcr.test(): "+tcr.test());
	}
	
	public int test(){
		int a = 0;
		
		try{
			System.out.println("a: "+a);
			a = 110;
			throw new Exception();                //try不能return,unreachable
		}catch(Exception e){
			a = a+3;
			return a;			
		}finally{
			a ++;
			System.out.println("finally a: "+a);
		}     
	}	
}

执行结果:

a: 0
finally a: 114
tcr.test(): 113

 

test()是从catch模块的return语句返回,执行过程类似测试2, finally模块是在catch模块的return执行之前才执行的,且catch模块的return返回值在finally模执行前确定的;

 

4.测试catch模块介入时return的返回顺序(finally有return);;

public class TryCatchReturn {	

	public static void main(String[] args) {		
		TryCatchReturn tcr = new TryCatchReturn();
		System.out.println("tcr.test(): "+tcr.test());
	}
	
	public int test(){
		int a = 0;
		
		try{
			System.out.println("a: "+a);
			a = 110;
			throw new Exception();                //try不能return,unreachable
		}catch(Exception e){
			a = a+3;
			return a;			
		}finally{
			a ++;
			System.out.println("finally a: "+a);
                                                return a;		
}     
	}	
}

执行结果:

a: 0
finally a: 114
tcr.test(): 114

 

test()是从finally模块的return语句返回的,catch模块的return可被认为是没有执行,且最终返回的是finally模块a的值;

 

 

 

4.总结

 

 1.无论是否有异常,finally块中的语句都会执行,无论try或catch模块是否有return;

 

2.若finally模块有return,无论try或catch模块中是否有return,程序段最终从finally的return返回;

但一般不推荐在finally语句中return;

 

3. 若finally模块无return,且try或catch模块有return,try或catch模块的return返回值在finally模块执行前就已经确定,然后执行finally模块,且但方法最终从return语句返回;

 

4.对于try-catch-finally语句之后的return语句,finally模块是在return前执行的,且return返回值在finally模执行后确定的;

1
2
分享到:
评论
3 楼 kakajw 2012-08-29  
try模块的return语句先于finally模块执行,但return并不立即返回,而是执行后,将把返回结果放置进函数栈中,待finally模块执行完后,又返回至try模块的return语句,退出方法,完成执行。因此,对于此种情况,可以认为try模块的return语句先于finally模块执行,但是方法最终还是从return语句返回退出的。


castte 写道
3. finally模块是在try或catch模块的return后才执行的,且try或catch模块的return返回值在finally模执行前就已经确定;

前半句不对吧, finally模块应该是在try或catch模块的return前执行的

2 楼 castte 2011-11-25  
3. finally模块是在try或catch模块的return后才执行的,且try或catch模块的return返回值在finally模执行前就已经确定;

前半句不对吧, finally模块应该是在try或catch模块的return前执行的
1 楼 sdujq 2011-02-24  
………………

相关推荐

Global site tag (gtag.js) - Google Analytics