Java初学注意小事项2——异常中的finally

finally通常发生在异常中的末尾
如下:

try{
		// 有可能发生异常的代码段 
	}catch(异常类型1 对象名1){ 
		// 异常的处理操作 
	}catch(异常类型2 对象名2){
		// 异常的处理操作 
	} ... 
	finally{ 
		// 异常的统一出口 
	} 
finally语句将作为异常的统一出口,不管是否产生了异常,最终都要执行此段代码。

疑问:
try-catch-finally 中,如果 try 中 return 了,finally 还会执行吗?
:finally中的代码会执行 。

详解:
执行流程:

  1. 先计算返回值, 并将返回值存储起来, 等待返回 ,比如放入
  2. 再执行finally代码块
  3. 将之前存储的返回值, 返回出去;
  4. 举例:比如return a1中,先计算a1,备份到x中等待返回;再执行finally中的a2;最后return x。因为finally的执行并不影响x,所以返回的还是值a1.

需注意
5. 返回值是在finally运算之前就确定了,并且缓存了,不管finally对该值做任何的改变,返回的值都不会改变 。
6. finally代码中不建议包含return,因为程序会在上述的流程中提前退出,也就是说返回的值不是try或catch中的值。
7. 如果在try或catch中停止了JVM(虚拟机),则finally不会执行.例如停电- -, 或通过如下代码退出 JVM:System.exit(0);``


返回值改变的有趣小案例

案例1:返回值不变

public static void main(String[] args){
	System.out.println(A());
}
//方法A
public static int A(){
	int age ;
	try{
		age = 18;
		return age;
	}catch(Exception e){
		return 0;
	}finally{
		age = 28;
	}
}

上述方法在main中调用后,返回值 age = 18;

案例2:返回值改变

public static void main(String[] args){
	Person p = B();
	System.out.println(p.age);
}
//调用Person
public static Person B(){
	Person p = new Person();
	try{
		p.age = 18;
		return p;
	}catch(Exception e){
		return null;
	}finally{
		p.age = 28;
	}
}
//方法Person
static class Person{
	int age;
}

上述方法在main中调用后,返回值 age = 28;


原理解释
在java中,基本数据如 int a ,int a = 18 等都存储在栈中;而类(class)则存储在堆中, 如 Person p 存储在栈中,而 p.age(类中的内容)则存储在堆中。
那么堆和栈如何联系呢?
此时栈相当于指针,存储了堆中的地址,凭借地址找到堆中的内容。

如下两幅图:
在这里插入图片描述

在这里插入图片描述
总结:所以finally中的备份一直不变,只是当存储的为地址时,所在地址存在的内容改变,则最终返回地址中的值改变。除非你返回的是finally中备份的地址。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值