Java:簡述try-catch-finally中return傳回
- 《Java:詳解Java中的異常(Error與Exception)》
- 《Java:簡述Java中的自定義異常》
- 《Java:簡述throw-throws異常抛出》
- 《Java:簡述try-catch-finally異常捕獲》
- 《Java:簡述try-catch-finally中return傳回》
提示:閱讀本文章之前可以先閱讀《Java:簡述try-catch-finally異常捕獲》
java中的 finally關鍵字通常與 try/catch塊一起使用。用來在方法結束前或發生異常時做一些資源釋放的操作。雖然看起來很簡單,在日常開發中也發現關于 finllay還是有些需要注意的地方。
一 . finally 語句塊一定會執行嗎?
很多人都認為 finally語句塊是肯定要執行的,比如下面的代碼,隻要進入了 try/catch塊,不管有沒有異常,都會執行 finllay塊。
public static void main(String[] args) {
System.out.println(test());
}
public static int test(){
try {
System.out.println("try block");
int i = 1 / 0;
return 0;
} finally {
System.out.println("finally block");
}
}
運作代碼輸出 :
try block
finally block
Exception in thread "main" java.lang.ArithmeticException: / by zero
但是答案是否定的,我們先來看下面這個例子:
public static void main(String[] args) {
System.out.println(test());
}
public static int test(){
try {
System.out.println("try block");
System.exit(0);
return 0;
} finally {
System.out.println("finally block");
}
}
運作代碼輸出 :
try block
我們在 try語句塊中執行了 System.exit (0)語句,終止了 Java 虛拟機的運作, finally語句塊就沒有執行。
其實,在下述4種特殊情況時,finally塊都不會被執行:
1)在finally語句塊中發生了異常。
2)在前面的代碼中用了System.exit()退出程式。
3)程式所在的線程死亡。
4)關閉CPU。
二 . 如果執行了finally,函數傳回值問題
我們先來看下面這個例子:
public static void main(String[] args) {
System.out.println(test());
}
public static int test(){
try {
System.out.println("try block");
int i = 1 / 0;
return 0;
} catch (Exception e) {
System.out.println("catch block");
return 1;
} finally {
System.out.println("finally block");
return 2;
}
}
運作代碼輸出 :
try block
catch block
finally block
2
對于上面的代碼,相信大部分人都能知道輸出值是 2,列印結果也确實是 2,就算把 int i = 1 / 0這一行注釋掉,列印結果也是 2。
是以在這裡我們可以下結論 : finally裡的 return語句會把 try/catch塊裡的 return語句效果給覆寫掉。
假如我們不在 finally中 return,結果會怎樣?我們再看看下面的例子 :
public static void main(String[] args) {
System.out.println(test());
}
public static int test(){
int i = 999;
try {
System.out.println("try block");
i = 1 / 0;
return i;
} catch (Exception e) {
System.out.println("catch block");
i = 100;
return i;
} finally {
System.out.println("finally block");
i = 200;
}
}
列印結果是 :
try block
catch block
finally block
100
雖然調用了 finllay改變了i的值,但是最後輸出還是 100,為什麼呢?
對于這種情況我的了解就是在 return的時候會把傳回值壓入棧,并把傳回值指派給棧中的局部變量, 最後把棧頂的變量值作為函數傳回值。是以在 finally中的傳回值就會覆寫 try/catch中的傳回值,如果 finally中不執行 return語句,在 finally中修改傳回變量的值,不會影響傳回結果。下圖為位元組碼檔案中的部分内容:
參考:https://mp.weixin.qq.com/s/FzVAXjk7Oj4ycLRH1nKQ1w