天天看點

Java:簡述try-catch-finally中return傳回

Java:簡述try-catch-finally中return傳回

  1. 《Java:詳解Java中的異常(Error與Exception)》
  2. 《Java:簡述Java中的自定義異常》
  3. 《Java:簡述throw-throws異常抛出》
  4. 《Java:簡述try-catch-finally異常捕獲》
  5. 《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中修改傳回變量的值,不會影響傳回結果。下圖為位元組碼檔案中的部分内容:

Java:簡述try-catch-finally中return傳回

參考:https://mp.weixin.qq.com/s/FzVAXjk7Oj4ycLRH1nKQ1w