天天看點

滴滴二面:try-catch-finally 和 return 是怎麼執行的?

最近一直在看Java虛拟機規範,發現直接分析bytecode更能加深對Java語言的了解。

之前看過一篇關于 return 和 finally 執行順序的文章,僅在 Java 的語言層面做了分析,其實我倒覺得直接看 bytecode 可能來的更清晰一點。

先看一個隻有 try-finally,沒有 catch 的例子。

try - finally

通過 javap -c ExceptionTest 來檢視它的位元組碼。

如果沒有抛出異常,那麼它的執行順序為

如果抛出了異常,JVM 會在

中進行控制跳轉。如果是位于0到4位元組之間的指令抛出了任何類型(any type)的異常,會跳轉到11位元組處繼續運作。

astore_1會把抛出的異常對象儲存到local variable數組的第二個元素。下面兩行指令用來調用成員方法wrapItUp。

最後通過

重新抛出異常。

通過以上分析可以得出結論:

在try-finally中,try塊中抛出的異常會首先儲存在local variable中,然後執行finally塊,執行完畢後重新抛出異常。

如果我們把代碼修改一下,在try塊中直接return。

try - return - finally

”反彙編“一下:

可以看出finally塊的代碼仍然被放到了return之前。

如果try塊中有return statement,一定是finally中的代碼先執行,然後return。

JVM規範是這麼說的:

Compilation of a try-finally statement is similar to that of try-catch. Pior to transferring control outside thetry statement, whether that transfer is normal or abrupt, because an exception has been thrown, thefinally clause must first be execute. try - catch - finally

給上面的代碼加一個catch塊

javap一下

通過Exception table可以看出:

catch監聽 0 ~ 4 位元組類型為TextExc的異常。

finally為 0 ~ 4 以及 11 ~ 17 位元組任何類型的異常。

也就說 catch block 本身也在 finally block 的管轄範圍之内。

如果catch block 中有 return statement,那麼也一定是在 finally block 之後執行。

滴滴二面:try-catch-finally 和 return 是怎麼執行的?
滴滴二面:try-catch-finally 和 return 是怎麼執行的?
上一篇: web開發-tools
下一篇: Web開發簡介