当try/catch...finally遇上return

try/catch

    异常(Exception)是平日里写代码过程中很常见的,可以分为运行时异常(RuntimeException)和非运行时异常(也叫编译异常)。运行时异常一般是程序逻辑错误引起的,可以选择进行try/catch捕获处理,也可以不处理;编译异常则必须要try/catch进行捕获,否则不能通过编译。当然今天的重点不在异常的讲解,而是由异常引出try/catch。
    说到try/catch自然而然的就会联想到finally,因为finally代码块必须与 try 或 try/catch 代码块配合使用。不管try代码块中的代码是否发生异常,finally代码块中的代码都会执行。

try/catch…finally遇上return

记得之前面试的时候,遇到这样一个问题:有一个方法,代码有try/catch包裹,该方法是有返回值的,问finally代码块和return哪个先执行。现在就来通过简单代码示例看一下到底谁先执行。
我用简单的代码模拟了一下问题的情景,代码如下:

  • 无异常情况:
public class Test {
    public static void main(String[] args) {
        System.out.println("i=" + new Test().test());
    }
    public int test() {
        int i = 1;
        try {
            i++;// i=2
            System.out.println("try...");
            return i;
        } catch (Exception e) {
            i++;
            System.out.println("catch...");
        } finally {
            i++;//i=3
            System.out.println("finally...");
        }
        return i;
    }
}

程序执行结果如下:
try…
finally…
i=2

执行try代码块,此时的i=2,这段代码没有异常发生,所以没有执行catch代码块中的代码(这也验证了不发生异常的情况下,finally代码块也会执行)。从执行结果可以看出return后i=2,说明return在finally之前执行的。

通过打断点调试,也验证了这个结论:

这里写图片描述

此时i=2且执行了return,继续向下执行进入finally代码块:

这里写图片描述

最终打印结果i=2。

  • 发生异常情况:
public class Test {
    public static void main(String[] args) {
        System.out.println("i=" + new Test().test());
    }
    public int test() {
        int i = 1;
        try {
            i++;//i=2
            System.out.println("try...");
            i = i/0;//除数为0,发生异常
            return i;
        } catch (Exception e) {
            i++;//i=3
            System.out.println("catch...");
        } finally {
            i++;//i=4
            System.out.println("finally...");
        }
        return i;
    }
}

运行结果如下:
try…
catch…
finally…
i=4

执行try代码块,此时的i=2,这段代码发生异常,所以执行catch代码块,此时i=3,然后执行finally代码块,此时i=4,最后执行return,返回i=4。这种情况下return在finally之后。

打断点调试如下:

这里写图片描述

发生异常,执行完finally代码块i=4,继续向下执行:

这里写图片描述

return返回i=4。

发生异常还有一种情况,return语句存在于catch代码块中,代码如下:

public class Test {
    public static void main(String[] args) {
        System.out.println("i=" + new Test().test());
    }
    public int test() {
        int i = 1;
        try {
            i++;//i=2
            System.out.println("try...");
            i = i/0;//除数为0,发生异常
            return i;
        } catch (Exception e) {
            i++;//i=3
            System.out.println("catch...");
            return i;
        } finally {
            i++;//i=4
            System.out.println("finally...");
        }
    }
}

运行结果如下:
try…
catch…
finally…
i=3

执行try 代码块后i=2,发生异常,执行catch代码块,此时i=3,然后return返回3,最后执行finally代码块。

打断点调试如下:

这里写图片描述

发生异常,执行catch代码块并返回return,继续执行finally:

这里写图片描述

总结

没有异常发生,先执行try代码块里面的return,然后执行finally;

当有异常发生,不执行try代码块里面的return,
    -return在try/catch以外时,finally在return前执行。
    -catch里有return时,return在finally前执行;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值