Java中try、catch、finally语句块的执行顺序

一、我们将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

猜你喜欢

转载自blog.csdn.net/cockroach02/article/details/80186723