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, return语句先于finally模块执行,try或catch模块的return返回值(若有的return的话)在finally模执行前就已经确定,且但方法最终是从return语句返回。

 

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

你可能感兴趣的:(finally)