关于finally的几个问题

 

1、Finally块中代码在什么时候执行?

package testfinally;

public class Test {

	public static int test(){
		try{
			
			return 1;
		}catch(Exception e){
			return 0;
		}finally{
			System.out.println("execute finally");
		}
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int result = test();
		System.out.println(result);
	}

}
结果输出:1

package testfinally;

public class Test {

	public static int test(){
		try{
			throw new Exception();
		}catch(Exception e){
			return 2;
		}finally{
			System.out.println("execute finally");
		}
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int result = test();
		System.out.println(result);
	}

}
结果输出:2

结果分析:finally块中代码在相应的try..catch块中执行return语句前执行。

2、finallyreturn语句覆盖try..catch中的return?

package testfinally;

public class Test {

	public static int test(){
		try{
			return 1;
		}catch(Exception e){
			return 2;
		}finally{
			System.out.println("execute finally");
			return 3;
		}
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int result = test();
		System.out.println(result);
	}

}
结果输出:3

package testfinally;

public class Test {

	public static int test(){
		try{
			throw new Exception();
		}catch(Exception e){
			return 2;
		}finally{
			System.out.println("execute finally");
			return 3;
		}
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int result = test();
		System.out.println(result);
	}

}
结果输出:3

结果分析:finallyreturn语句覆盖try..catch中的return,直接在finally返回。

3、finally里的返回基本类型和引用型对象的问题

package testfinally;

public class Test {

	public static int test(){
		int result = 0;
		try{
			result = 1;
			return result;
		}catch(Exception e){
			result = 2;
			return result;
		}finally{
			result = 3;
			System.out.println("execute finally");
		}
	}
	
	public static String test2(){
		String result;
		try{
			result = new String("aaa");
			return result;
		
		}catch(Exception e){
			result =  new String("bbb");
			return result;
		}finally{
			result =  new String("ccc");
			System.out.println("execute2 finally");
		}	
	}
	
	public static StringBuffer test3(){
		StringBuffer result = new StringBuffer("hello");
		try{
			return result;
		
		}catch(Exception e){
			return null;
		}finally{
			result.append(" world");
			System.out.println("execute3 finally");
		}	
	}
	
	public static Person test4(){
		Person p1 = new Person(11,"张三");
		try{
			return p1;
		
		}catch(Exception e){
			return null;
		}finally{
			p1.setAge(12);
			p1.setName("李四");
			System.out.println("execute4 finally");
		}	
	}
	
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int result = test();
		System.out.println(result);
		
		String result2 = test2();
		System.out.println(result2);
		
		StringBuffer result3 = test3();
		System.out.println(result3.toString());
		
		Person result4 = test4();
		System.out.println(result4.toString());
	}

}

结果输出:

1
execute2 finally
aaa
execute3 finally
hello world
execute4 finally
name: 李四;age: 12

分析结果:由于在一个方法内部定义的变量都存储在栈中,当这个函数结束后,其对应的栈就会被回收,此时在其方法体中定义的变量将不存在,因此return返回时不是直接返回变量的值,而是先产生一个副本暂存,最后返回该副本。因此对于基本类型的数据,在finally块中改变return的值对返回的副本值没有任何影响。而对于引用型变量,当产生一个副本时,对于引用对象型数据并没有重新复制一份,而是指向了原来的数据,所以改变引用型中的对象数据,也就改变了副本中的引用型对象数据。对于test2的返回结果和test1一样是因为,引用型变量又指向了重新的定义的对象,而并为对其指向的对象型数据进行改变,所以没有引起副本中的对象型数据发生改变。


4、副本是在什么情况下产生的呢?

package testfinally;

public class Test {

	public static int test(){
		int result = 0;
		try{
			result = 1;
			//return result;
		}catch(Exception e){
			result = 2;
			//return result;
		}finally{
			result = 3;
			System.out.println("execute finally");
		}
		return result;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int result = test();
		System.out.println(result);
		
	}

}
输出结果:3

package testfinally;

public class Test {

	public static int test(){
		int result = 0;
		try{
			result = 1;
			return result;
		}catch(Exception e){
			result = 2;
			//return result;
		}finally{
			result = 3;
			System.out.println("execute finally");
		}
		return result;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int result = test();
		System.out.println(result);
		
	}

}

输出结果:1

结果分析:

所以我认为在有return语句的try或者catch语句块里创建副本




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值