当前位置 博文首页 > 换了马甲的小强的博客:Java中try、catch、finally语句块的执行

    换了马甲的小强的博客:Java中try、catch、finally语句块的执行

    作者:[db:作者] 时间:2021-08-01 20:55

    一、我们将try{}catch(){}finally{}分成以下几种情况分别验证:

    场景1:try{return;}catch{}finally{} return;

        public static int returnSttat(int i) {
            System.out.println("return block");
            return i;
        }
    
        public static int test01() {
            int i = 0;
            try {
                i = 1;
                return returnSttat(i);
            }catch (Exception e) {
    
            } finally {
                System.out.println("finally block01");
            }
            return 0;
        }

    执行结果如下:

    return block
    finally block01
    1

    执行步骤: a) 执行try{}部分(包括return表达式); b) 执行finally{}部分; c) 返回try{}中return表达式结果.

    场景2:try{}catch{}finally{} return 有异常场景;

        public static int returnSttat(int i) {
            System.out.println("return block");
            return i;
        }
        public static int test01() {
            int i = 1;
            int divid = 0;
            try {
                int n = i / divid;
            } catch (Exception e) {
                System.out.println("catch block");
                return returnSttat(i);
            } finally {
                System.out.println("finally block");
            }
            return 0;
        }

    执行结果如下:

    catch block
    return block
    finally block
    1

    执行顺序: a) 执行try块抛出异常;b)catch拦截了异常并执行处理逻辑; c) 执行try中return 表达式;d)执行finally块; e) 执行return表达式返回值

    场景3: try{return;} catch{} finally{return;}

        public static int returnSttat(int i) {
            System.out.println("return block");
            return i;
        }
        public static int test01() {
            int i = 1;
            try {
                System.out.println("try block");
                return returnSttat(i);
            } catch (Exception e) {
                System.out.println("catch block");
            }finally {
                System.out.println("finally block");
                return returnSttat(0);
            }
        }

    执行结果如下:

    try block
    return block
    finally block
    return block
    0

    执行顺序: a) 执行try块,并执行其中return表达式; b) 执行finally块; c) 执行finally中return 表达式;d) 返回finally中return表达式结果(PS:由于finally中有return语句则直接返回退出)

    场景4:try{return;} catch{} finally{return;}有异常

        public static int returnSttat(int i) {
            System.out.println("return block" + i);
            return i;
        }
        public static int test01() {
            int i = 1;
            int j = 0;
            try {
                System.out.println("try block");
                int k = i / j;
                return returnSttat(i);
            } catch (Exception e) {
                System.out.println("catch block");
                return returnSttat(-1);
            }finally {
                System.out.println("finally block");
                return returnSttat(0);
            }
        }

    执行结果:

    try block
    catch block
    return block-1
    finally block
    return block0
    0

    执行顺序: a) 执行try块,并抛出异常; b) catch获取异常,执行其中语句,并执行其中return语句;c) 执行finally块中语句并执行return语句;d)返回finally语句中return结果集(由于finally中有return则直接返回退出)

    场景5: try{}finally{}中引用类型对象发生修改

        public static User test01() {
            User user = new User("kk");
            try{
                System.out.println("try block: " + user);
                return user;
            } finally {
                System.out.println("finally block: " + user);
                user.name = "jj";
            }
        }
    
        static class User {
            String name;
            User(String name) {
                this.name = name;
            }
    
            @Override
            public String toString() {
                return hashCode() + ":"+ name;
            }
        }

    执行结果:

    try block: 780376:kk
    finally block: 780376:kk
    780376:jj

    执行步骤: a) 执行try{}中块并执行return user语句;b)执行finally语句修改了u的属性name;c)返回u。(PS user属性竟然发生改变啦!)

    场景6: try{}finally{}中引用类型对象返回

        public static User test01() {
            User user = new User("kk");
            try{
                System.out.println("try block: " + user);
                return user;
            } finally {
                user = new User("jj");
                return user;
            }
        }
    
        static class User {
            String name;
            User(String name) {
                this.name = name;
            }
    
            @Override
            public String toString() {
                return hashCode() + ":"+ name;
            }
        }

    执行结果:

    try block: 780376:kk
    29092282:jj

    执行步骤 : 与场景3同

    二、总结
    1. 在try中return,在finally执行前会把结果保存起来,即使在finally中有修改也以try中保存的值为准,但如果是引用类型,修改的属性会以finally修改后的为准;
    2. 如果try/finally都有return,直接返回finally中的return。
    3. 不管try,finally都会执行;
    4. 永远不要在finally块中使用return(PS: 提醒自己)

    三、参考链接:
    1. java中关于try、catch、finally的总结
    2. Java趣味分享:try/finally

    cs