當return遇到finally
看過網上關于Java中異常捕獲機制try…catch…finally塊中的finally語句是不是一定會被執行的讨論也有很多。
首先明确一點,下面兩種情況finally肯定是不執行的:
1). return語句在try之前,還沒執行就傳回了,當然不執行。
2). try語句中用了system.exit(0)強制退出JVM,暴力退出當然也不會執行。
先來看下面的代碼
package com.loongshaw;
public class TryReturnFinally {
public static void main(String[] args) {
System.out.println(test1());
}
public static int test1() {
int b = ;
try {
System.out.println("try block");
return ++b;
}
catch (Exception e) {
b = ;
System.out.println("catch block");
}
finally {
++b;
System.out.println("finally block");
}
System.out.println("last block");
return b;
}
}
如果你覺得其執行結果是3,那麼請你繼續看下去,中招了吧,哈哈。
先看看執行結果吧:
try block
finally block
可以看出,上面代碼的執行結果是2。正常想法其finally也執行了,try中也執行了,明明執行了兩個++b呢,咋回事呢?
這個時候,咱打斷點看看:
(1). 當程式執行到try中的return語句時,這時b還是1.

(2). 接着程式執行到finally語句時,執行了++b,b變為2.
(3). 這時,我們點選try…return中的b,發現其值變為2.
以上結果說明了一點:return語句執行了,然後再執行了finally語句,但是return語句并沒有直接傳回,而是待finally語句執行完了再傳回。
通過下面這個測試用例加強了解:
package com.loongshaw;
public class TryReturnFinally {
public static void main(String[] args) {
System.out.println(test2());
}
public static String test2() {
try {
System.out.println("try block");
return test3();
}
catch (Exception e) {
System.out.println("catch block");
}
finally {
System.out.println("finally block");
}
System.out.println("last block");
return "last block";
}
public static String test3() {
System.out.println("return block");
return "output return block";
}
}
執行結果:
try block
return block
finally block
output return block
通過上述結果可以得出,在執行try語句中的return時,其test3()方法是被執行了的,其傳回值儲存在一個臨時變量中,然後去執行finally語句。
try {
System.out.println("try block");
return test3();
}
最後輸出存進臨時變量傳回值。
output return block
可能大家會繼續說,如果finally和catch中有return,那是一種什麼情況:
(1) 首先看catch中有return
public static int test4() {
int b = ;
try {
System.out.println("try block");
return b/;
}
catch (Exception e) {
System.out.println("catch block");
return ++b;
}
finally {
b = b+ ;
System.out.println("finally block");
}
}
結果
try block
catch block
finally block
可見,catch中的return與try一樣,finally都會執行,但是不影響try和catch中的return結果。
(2) 然後看finally中有return
public static int test5() {
int b = ;
try {
System.out.println("try block");
return ++b;
}
catch (Exception e) {
++b;
System.out.println("catch block");
return b;
}
finally {
b = b+ ;
System.out.println("finally block");
return b;
}
}
結果
try block
finally block
可見,finally中的return直接傳回了,這與try和catch中的return是不同的。
大家可能發現test1()方法最後的return是沒有執行的,是不是。
public static int test1() {
...
System.out.println("last block");
return b;
...
}
通常情況是不會執行的,除非觸發了catch。下面是修改後的片段代碼:
public static int test1() {
int b = ;
try {
b = b/;
System.out.println("try block");
return ++b;
}
catch (Exception e) {
b = ;
System.out.println("catch block");
}
finally {
b = b+ ;
System.out.println("finally block");
}
System.out.println("last block");
return b;
}
執行結果:
catch block
finally block
last block
通過上述結果可以得出,在catch觸發時,最外層的return是會被執行的。
總結:
- finally語句在try和catch語句中的return執行後、傳回前執行;
- 若finally語句中沒有return,則其執行結果不影響try和catch中已确定的傳回值;
- 若finally語句中有return,則其執行後的結果會直接傳回。