try-catch-finally-return的执行先后顺序问题

本文记录两种比较绕的情况
前提:不管有没有异常,finally块中代码都会执行
情况1. catch 和 finally 中都有return 的情况,执行步骤 1、3、5、6(但是步骤五没有看到Log 工具AS 段点调试)返回值是2.
- 不要在finally 中 retrun因为在 finally 中是释放资源的,这么做就是在犯罪。
- 猜测了一下,是不是在finally 中所有的操作都是无效的?
- 为什么没有走步骤四 ?。我猜想应该是被finally 中的retrun 顶掉了 (我的拳头大,我说了算)

 private static int mian() {
        try {
            System.out.println("println====");// 步骤一
            int y = 10086 / 0;
            return 0;                           // 步骤二
        } catch (Exception e) {
            System.out.println("Exception====");// 步骤三
            return 1;                             // 步骤四
        } finally {
            System.out.println("finally===");   // 步骤五
            return 2;                            // 步骤六
        }
    }

情况2: catch return和 finally 没有 的情况 执行步骤 1、3、4、5、4;返回1

  • 为什么走了两次步骤四?举例说明:return 同学要从31楼下一楼了,扭头一看后面 还有finally 同学,(4)然后就问他,你下不下去?不下去我下去了?(5)finally 同学说等等我,扫完地就下去,(4)然后return 等finally 干完活一起下去了
    private static int mian() {
        try {
            System.out.println("println====");// 步骤一
            int y = 10086 / 0;
            return 0;                           // 步骤二
        } catch (Exception e) {
            System.out.println("Exception====");// 步骤三
            return 1;                             // 步骤四
        } finally {
            System.out.println("finally===");   // 步骤五
            //return 2;                            // 步骤六
        }
    }

2018 06 28 新增

 public static Map<String, String> getMap() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("KEY", "INIT");

        try {
            map.put("KEY", "TRY");
            return map;// 没走
        } catch (Exception e) {
            map.put("KEY", "CATCH");
        } finally {
            map.put("KEY", "FINALLY");
            map = null;
        }

        return map; // 这里return
    }

结果 :System.out: FINALLY
大神讲解(地址忘记了,有看到可以联系补上)

try语句中的return map;会做哪些操作呢(针对字节码来说)首先解释一个概念,对于堆中对象的引用在局部变量表用reference表示,这里我们暂且认定局部变量表中有一个reference0指向堆内存中map对象。return map; 首先会将reference0指向的map对象压栈,然后弹出栈到局部变量表中referebce1中,即现在两个引用指向堆中的map对象。finally代码块的中操作都是针对reference0引用,也就是说map=null;只是对reference0影响,但局部变量表中还有个引用指向map对象的。return 返回的是reference1 也就是”复制”的引用。

个人理解(真假美猴王的例子):西天取经走到finally这一关的时候,嘚,冒出来一个假美猴王,你会的我也会(地址指向相同),在finally中真美猴王各种操作,(添加FINALLY),闹到 如来 那里,佛祖一个金钵把真美猴王收了(map==null),反正除了如来,地听,谁知道哪个是真的假的?我估计地听也不知道,官人想过这个问题吗?悟空 卒,六耳猕猴扛着掉落的装备(金箍棒、map里的内容)去西天了,如来得到了想要的结果。故事完!

猜你喜欢

转载自blog.csdn.net/guojiayuan002/article/details/80818585