揭开“finally”的神秘面纱

本文详细探讨了finally语句在Java中的使用场景及执行时机,包括在return前后的行为表现,并通过多个实例验证了finally语句的特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                                   揭开“finally”的神秘面纱

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



考点


这个题目也是考查异常相关的。对于这个题目,我们通过代码来验证我们的答案,因为有异议的知识点,代码是最有说服力的。对于编程,希望你记住“不与人争辩,一切用代码说话”。

1什么时候用到finally呢?

某些事物(除内存外)在异常处理完后需要恢复到原始状态,如:开启的文件,网络连接等。

2finally语句在try或catch中的return语句执行之后,还是return返回之前执行呢?

这个问题是一个很经典的问题,经常被面试官问,如果自己不去实验一下,可能判断就会出错。我们结合代码来分析一下。下面我们通过4个demo来得出最终结论。

01

private static int test1() {

        int i = 1;

        try {

            System.out.println("try...");

            return i += 10;

        } catch (Exception e) {

            System.out.println("catch...");

        } finally {

            i++;

            System.out.println("finally...");

            System.out.println("i=" + i);

        }

        return i;

}


执行结果:

try...

finally...

i=12

test1:11


总结:finally代码块是在try代码块中的return语句执行之后,返回之前执行的。

02

private static int test2() {

        int i = 1;

        try {

            System.out.println("try...");

            return i += 10;

        } catch (Exception e) {

            System.out.println("catch...");

        } finally {

            i++;

            System.out.println("finally...");

            System.out.println("i=" + i);

            return i;

        }

}


执行结果: 

test2:12

try...

finally...

i=12


总结:finally代码块中的return语句覆盖try代码块中的return语句。

03

private static Map<String, String> test3() {

        Map<String, String> map = new HashMap<String, String>();

        map.put("KEY", "INIT");

        try {

            System.out.println("try...");

            map.put("KEY", "TRY");

            return map;

        } catch (Exception e) {

            System.out.println("catch...");

            map.put("KEY", "CATCH");

        } finally {

            System.out.println("finally...");

            map.put("KEY", "FINALLY");

            map = null;

        }

        return map;

}


执行结果: 

try...

FINALLY

finally...


总结: 如果finally语句中没有return语句覆盖返回值,那么原来的返回值可能因为finally里的修改而改变也可能不变。传值类型的返回值:不变;传址类型的返回值:会变。

这里引入来一个新的问题,怎么判断一个变量是传值还是传址?

传值:8种基本数据类型及其包装类,字符常量。传址:数组和对象。





04

private static int test4() {

        int i = 1;

        try {

            System.out.println("try...");

            i = i / 0;

            return i += 10;

        } catch (Exception e) {

            System.out.println("catch...");

            return i;

        } finally {

            i++;

            System.out.println("finally...");

            System.out.println("i=" + i);

        }

}

执行结果: 

try...

catch...

finally...

i=2

1


总结: try代码块中的return语句在异常的情况下不会被执行,这样具体返回哪个看情况;catch中的return执行情况与未发生异常时try中return的执行情况完全一样。


根据上面的分析,咱们汇总一下答案:

  1. try语句没有被执行,如在try语句之前就返回了,这样finally语句就不会执行;因此说明了finally语句被执行的必要而非充分条件是:相应的try语句一定被执行到。

  2. 如果在try代码块中执行System.exit(0)语句;那么将终止Java虚拟机JVM,因此,finally语句也不会被执行到。

  3. finally块的语句在try或catch中的return语句执行之后返回之前执行且finally里的修改语句可能影响也可能不影响try或catch中return已经确定的返回值,如果返回值类型为传址类型,则影响;传值类型,则不影响。若finally里也有return语句则覆盖try或catch中的return语句直接返回。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值