为什么finally块一定会执行?

示例代码一:

public class TestMain {

    public static void main(String[] args) {
        try {
            System.out.println("1");
        } catch (Exception e) {
            System.out.println("2");
        } finally {
            System.out.println("3");
        }
    }
}

输出结果如下:
在这里插入图片描述

再看一个会出现异常的示例代码二:

public class TestMain {

    public static void main(String[] args) {
        try {
            int i = 1 / 0;
        } catch (Exception e) {
            System.out.println("2");
        } finally {
            System.out.println("3");
        }
    }
}

输出结果如下:
在这里插入图片描述

从两种结果都可以看出,无论有没有发生异常,finally块中的代码一定会被执行。

为什么finally块中的代码一定会被执行

直接从字节码的层面来分析原因

示例代码一的部分字节码:

在这里插入图片描述

示例代码二的部分字节码:

在这里插入图片描述

以上标注的一,二,三3部分的字节码,一部分代表了try块里的逻辑,二部分代表了catch块里的逻辑,三部分代表了finally块里的逻辑(这里没有把字节码划分的很清晰,只是把为了分析大致划出了3部分界限)

然后可以发现一部分和二部分都出现了三部分的字节码。

总结

从上述的字节码例子中可以得出结论,编译器在编译Java代码的时候,会把finally代码块里的内容,复制一份,分别放在try块和catch块里所有正常执行路径以及异常执行路径的出口中,从反编译的字节码里也很容易就能看出finally里的字节码存在多份,所以这就是finally块一定会执行的原因了。

发布了297 篇原创文章 · 获赞 311 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/weixin_38106322/article/details/105182866