- [x] try里有return,finally還執行么?那么緊跟在這個try后的finally{}里的code會不會被執行,什么時候被執行,在return前還是后
- [x] 如果執行finally代碼塊之前方法返回了結果,或者JVM退出了,finally塊中的代碼還會執行嗎
- [x] 在什么情況下,finally語句不會執行
一、try里有return,finally怎么執行
- finally塊里的代碼是在return之前執行的。
在異常處理中,無論是執行try還是catch,finally{}中的代碼都會執行(除非特殊情況)。由于程序執行return就意味著結束對當前函數的調用并跳出這個函數體,因此任何語句要執行都只能在return前執行。
public class Test {
public static int testFinally() {
try {
return 1;
} catch (Exception ex) {
return 2;
} finally {
System.out.println("execute finally");
}
}
public static void main(String[] args) {
int result = testFinally();
System.out.println(result);
}
}
運行結果:
execute finally
1
- 此外,如果try-catch-finally中都有return,那么finally塊中的return將會覆蓋別處的return語句,最終返回到調用者那里的是finally中return的值。
public class Test {
public static int testFinally() {
try {
return 1;
} catch (Exception ex) {
return 2;
} finally {
System.out.println("execute finally");
return 3;
}
}
public static void main(String[] args) {
int result = testFinally();
System.out.println(result);
}
}
運行結果:
execute finally
3
return語句并不一定都是函數的出口,執行return時,只是把return后面的值復制了一份到返回值變量里去了。
- 此外,在try/catch中有return時,在finally塊中改變基本類型的數據對返回值沒有任何影響;而在finally中改變引用類型的數據會對返回結果有影響。
/**
* try/catch中有return,在finally{}中改變基本數據類型、引用類型對運行結果的影響
*/
public class Test {
public static int testFinally1() {
int result1 = 1;
try {
return result1;
} catch (Exception ex) {
result1 = 2;
return result1;
} finally {
result1 = 3;
System.out.println("execute testFinally1");
}
}
public static StringBuffer testFinally2() {
StringBuffer result2 = new StringBuffer("hello");
try {
return result2;
} catch (Exception ex) {
return null;
} finally {
result2.append("world");
System.out.println("execute testFinally2");
}
}
public static void main(String[] args) {
int test1 = testFinally1();
System.out.println(test1);
StringBuffer test2 = testFinally2();
System.out.println(test2);
}
}
運行結果:
execute testFinally1
1
execute testFinally2
helloworld
程序在執行到return時會先將返回值存儲在一個指定位置,其次去執行finally塊,最會再return。
在finally塊中改變基本類型的數據result1/引用類型數據result2的值,與java的值傳遞和引用傳遞相關。值傳遞中,形參和實參有著不同的存儲單元,對形參的改變不會影響實參的值;引用傳遞中,傳遞的是對象的地址,形參和實參的對象指向同一塊存儲單元對形參的改變就會影響實參的值。
二、如果執行finally代碼塊之前方法返回了結果,或者JVM退出了,finally塊中的代碼還會執行嗎//finally不會執行的情況
- java程序中的finally塊并不一定會被執行。
至少有兩種情況finally語句是不會執行的。
(1)try語句沒有被執行到。
即沒有進入try代碼塊,對應的finally自然不會執行。
比如,在try語句之前return就返回了,這樣finally不會執行;
或者在程序進入java之前就出現異常,會直接結束,也不會執行finally塊。
(2)在try/catch塊中有System.exit(0)來退出JVM。
System.exit(0)是終止JVM的,會強制退出程序,finally{}中的代碼就不會被執行。