我們經常會使用try/catch/finally語句塊。當然,return關鍵字使用也是很平常的事,但是不知道大家有沒有注意個這樣乙個問題。當在try語句塊裡面使用return語句,在finally裡面去修改return所要返回的內容會出現什麼情況。首先,我們知道return是結束方法的標誌,一旦方法執行到return語句就將返回不再往下執行。其次,我們也知道,finally裡面的語句是無論方法怎樣執行,最後都要執行finally裡面的語句。那麼究竟是先執行return還是finally呢?下面通過兩個小實驗來解決這個問題。
首先看第乙個例子:
public class testtrycatch
public int fun()
catch(exception e)finally
}
}
輸出結果:10
ok很簡單的乙個例子,建立了乙個方法fun,在方法裡使用try/catch語句,方法要求返回值型別為int型。在try裡面放回i,這個時候是10,但是在finally裡面將i值修改為20。我們看到結果是10,好像是return先執行。那麼接下來再看另乙個例子:
public class testtrycatch
public stringbuilder fun()
catch(exception e)finally
}
輸出結果:hellowordfinally
看結果似乎有點出乎意料了,因為這次finally裡面修改的內容生效了。看**其實差別不大,只是把返回值型別修改為stringbuilder了。那麼這是為什麼呢?下面就為大家解釋一下其中到底是怎麼執行的。
首先,拿第乙個例子來說,可以在main方法裡實現這樣一條語句:int result = test.fun();我們知道這樣做是沒有問題的,但是大家都知道「=」號賦值是常量賦值。但是,方法的存放位址和常量的存放位址是不一樣的,方法的存放在**區的。上面我們把乙個方法賦值給乙個int型也沒有報錯。那是因為在宣告方法是我們宣告了返回值型別。那麼編譯器就會在**的最前端預留一段返回值型別的記憶體。執行return的時候,就會把返回的內容寫入到這段記憶體中
這樣,執行「=」號賦值的時候,就能在記憶體中匹配到相同的型別。賦值便能成功。
弄清楚上面的道理之後,再來解釋最開始提出的問題就容易多了。在執行了return之後,返回的值已經被寫入到那段記憶體中了,finally再修改i的值,只是修改了後面**段的i值,對返回段記憶體沒有影響。至於第二個例子,再看下面這張圖你就會明白。
我們可以看到,當返回值不是基本資料型別的時候,其是指向一段記憶體的,return將返回段指向一段記憶體,但是**段的s依然是指向的同一段記憶體位址,所以當s修改它指向記憶體中的值的時候,其實也就修改了返回段指向記憶體中的值,所以最終的值改變了。
到底返回值變不變可以簡單的這麼記憶:當finally呼叫的任何可變api,會修改返回值;當finally呼叫任何的不可變api,對返回值沒有影響。
當finally和return並存時的執行情況
public class trydemo finally public static void main string args 輸出結果 執行finally模組 0由此得出結論 當 try 塊和 catch 塊中有 return 語句時,finally 仍然會被執行。執行 try 塊或 catch...
return和finally執行順序
public class test public static int tt catch exception e finally system.out.println finally system.out.println come here return b 執行結果 yesb 25 111 fin...
java中finally和return的執行順序
注意 return的位置。從這幾個例子中可以看到,如果try之前沒有有條件的return,則try.catch finally語句塊中的語句都是順序執行 如果try中或者catch中 有return語句,那麼先執行該return,然後執行finally,如果finally中也有return,該出的返...