try catch finally的底層原理

2021-10-21 22:43:00 字數 2580 閱讀 3080

昨晚參加乙個面試,被問到try catch finally相關的知識,雖然之前了解過其中奇怪的用法,特別有return的情況,但是由於時間久遠,完全忘了,導致這個問題回答不是很好,只是知道finally無論是否發生異常都會執行的(但是忘了含有return的情況是怎麼處理的了),finally常常用來關閉一些資源,像檔案,連線等。

我們先來驗證一下finally終究執行

public

static

inttest()

finally

return i;

}public

static

void

main

(string[

] args)

輸出為

從上面兩個例子中我們可以看到,無論是正確執行try塊還是在try塊發生了異常,finally塊都是被執行的

finally不帶return的情況

public

static

inttest()

finally

}public

static

void

main

(string[

] args)

第乙個問題:在try塊中含有return語句,你覺得finally語句還有執行麼?

第二個問題:最終結果是多少?

從上面可以看到,儘管try塊裡面有return, 但是finally塊仍然執行了,你肯定會好奇,那為啥返回值是2呢,finally裡面不是還進行了i++麼。

簡單分析一下,從結果看,finally仍然執行,說明try的return語句是還沒執行的,下面我們看看位元組碼。

上面已經標註很清楚了,如果還不明白的話,可以先去看一下這幾個位元組碼命令,還是挺簡單的,注意的是,jvm操作都是基於運算元棧的。

總結一下,總體的意思就是,當執行完try塊的時候,會計算return表示式的值,然後把這個返回值存在另乙個臨時變數裡面,最後返回的時候會重新讀取存放的變數,因此在finally後面無論如何修改,都不會影響返回值(除非finally裡面含有return,這個我們在下面討論)

上面的情況是try或者catch裡面含有return,finally沒有return, 那麼fianlly裡面如何修改返回值是不會影響最後的返回值。下面討論finally裡面含有return的情況。

public

static

inttest()

finally

}public

static

void

main

(string[

] args)

相信各位能夠正常猜出結果了

沒錯,返回了3,說明finally對i的修過是其效果的,我們從位元組碼看看原因:

從上圖可以看到,在返回之前,載入的是0槽位的變數,這時0槽位的變數的值是3,1槽位的變數是2,所以返回的3。

由上可以得知,當finally中含有return的時候,會覆蓋之前try或者catch(上面沒有貼出實驗,需要驗證的可以去驗證,作者本人是驗證過了)裡面的返回值的

這種情況比較簡單,跟finally含有return類似

public

static

inttest()

finally

return i;

}public

static

void

main

(string[

] args)

這裡總結一下,只要finally裡面沒有return語句,那麼返回值就由try或者catch的return語句決定,否則由finally的return語句決定

try catch finally執行順序

public class test public static int ma catch exception e finally 說明 不出現異常情況 執行順序 try finally 出現異常情況 執行順序 try catch finally try中有返回語句,沒有異常 執行順序 try ret...

try catch finally執行順序

結論 1 不管有木有出現異常,finally塊中 都會執行 2 當try和catch中有return時,finally任會執行 3 finally是在return表示式運算後前執行的,所以函式返回值是在finally執行前確定的 4 finally中最好不要包含return,否則程式會提前退出,返回...

try catch finally使用體會

try catch finally public class finallytest static int test finally 結果是2。在try語句中,在執行return語句時,要返回的結果已經準備好了,就在此時,程式轉到finally執行了。在轉去之前,try中先把要返回的結果存放到不同於...