关于Java finally的面试题(finally的执行时机,finally和return的先后顺序)

**

关于Java finally的面试题(finally的执行时机,finally和return的先后顺序)

**
面试官问题:
什么时候用到finally呢?finally语句在try或catch中的return语句执行之后,还是return返回之前执行呢?

在try{}catch{}捕获异常处理语句中:
finally{}必然执行的异常统一处理出口,无论是否发生异常,finally必然执行
除非程序被关闭了 finally才不会执行 电脑关机了 软件在内存里没了 否则finally必然执行

那么执行顺序用代码来解释
看下面这部分代码:

public class Demo1 {
    public static void main(String[] args) {
        Person p1 = people();
        System.out.println(p1.age);
    }
    public static class Person{
        int age;
    }
    public static Person people(){
        Person p = new Person();
        try {
             p.age = 12;
             return p;
        }catch (Exception e){
             return null;
        }finally {
             p.age = 20;
            }
        }
}

这段代码不会产生异常
可能你觉得输出结果是12,但实际上他的返回结果是20
在这里插入图片描述
因为finally{},无论程序是否发生异常都必然执行return代表执行完毕,return下面的语句不执行,但在return返回值得时候他有一段备份的时间,而finally就是在备份的这段时间执行的,所以值是20
因此finally是在return后执行的

再看下面这段代码:

public class Demo2 {
    public static void main(String[] args) {
        int s = people2();
        System.out.println(s);
    }
    public static int people2(){
        int i = 12;
        try {
            i = 15;
            return i;
        }catch (Exception e){
            return 0;
        }finally {
            i = 20;
        }
    }
}

你觉得这个结果是20,那么你又错了,这个结果为15.
在这里插入图片描述
为什么会产生这种原因,就是下面要说的关于基本数据类型引用数据类型的区别
基本数据类型存在于栈里,那么return备份的就是数据。而finally改变的是栈里的数据,但是不会改变备份数据,所以返回值不变。
如下图
在这里插入图片描述
而引用数据类型,数据存在于堆中开辟的空间里,而栈中存储的是堆的所对应的空间地址,因此return备份的是栈中的空间地址,但是finally改变的是堆中的数据,所以当return返回地址时,查找到堆中的数据就是被改变了
如下图
在这里插入图片描述
那么看完了上面,下面要说的就是fially{}不执行的条件
代码如下:

public class demo3 {
        public static void main(String[] args) {
            people3();
        }
        public static void people3(){
            try {
                int i = 10;
                int j = 0;
                System.out.println(i/j);
            }catch (Exception e){
                System.out.println("出现了异常程序强制退出!");
                System.exit(0);
            }finally {
                System.out.println("程序结束");
            }
        }
}

这部分代码因为除数不能为0,所以会抛出异常,进入到catch{}里面,在catch里面有一行代码System.exit(0); 这一行代码的意思就是强制退出程序,因此finally不会执行
结果如下:没有输出程序结束
在这里插入图片描述
退出代码:System.exit( 0)可以输入0.1.2.3 0表示正常退出 剩下是非正常退出

总结如下:
1. finally{}必然执行的异常统一处理出口,无论是否发生异常,finally必然执行
2. 除非程序被关闭了 finally才不会执行 电脑关机了 软件在内存里没了 否则finally必然执行
3. 如果是基本数据类型先return 后finally 不会改变值 因为return备份的是值
4. 如果是引用数据类型 先return 后finally 会改变值, 因为return备份的是引用类型在堆中的地址 而finally改变的是堆中的值

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值