掘金 后端 ( ) • 2024-04-02 11:04

theme: smartblue

演示案例

public int zou() {
    int a = 0;

    try {
        a = 1;
        return 1;
    } catch (Exception c) {
        a = 2;
        return 2;
    } finally {
        a = 3;
        return 3;
    }

}

想必这段代码大家都能够非常轻松的理解

大家思考一下我们在面试中是不是有遇到过这种问题 :finally一定会执行吗?答案肯定是不会的。

先贴个答案

  • 在前面的代码中调用了System.exit()
  • JVM崩溃了
  • 线程被杀死
  • 操作系统关机
  • 无限循环或阻塞
  • 除去这些极端情况finally一般都会执行

为什么finally在正常情况下一定会执行呢?

问题一:finally是如何工作的

image.png 通过查看字节码就可以知道:

这个问题非常简单,就是在我们程序编译的时候会将finally的代码复制到try以及catch代码块的最后。(如果在try以及catch中有return这个return就会将它放到最末尾,这个时候finall有return那么finally的return会先执行)

那么在这个时候如果在catch代码中出现异常该怎么办呢?在了解这个问题的时候需要需要先了解catch代码是如何工作的。

问题二:catch是如何工作的

catch的执行需要依靠一个东西,“异常表”

image.png

image.png

这个是我们程序的异常变量表。

现在根据异常表的说法就是在try执行逻辑中如果出现了指定的异常那么就跳转到指定的PC行去执行。

总结

我想现在我们的答案应该是非常明确了:在正常执行的情况依靠的是拼接到try以及catch后finally执行,在程序出现错误的情况就依靠异常表中的记录跳转到指定的PC行去执行。