Java中finally與return的執行順序

2020-07-16 10:05:16
在 Java 的例外處理中,try、catch 和 finally 是按順序執行的。如果 try 中沒有異常,則順序為 try→finally,如果 try 中有異常,則順序為 try→catch→finally。但是當 try、catch、finally 中加入 return 之後,return 和 finally 的執行順序讓很多人混淆不清。下面來分別說明一下。

1. try 和 catch 中帶有 return

1)try 中帶有 return
public class tryDemo {
    public static int show() {
        try {
            return 1;
        } finally {
            System.out.println("執行finally模組");
        }
    }

    public static void main(String args[]) {
        System.out.println(show());
    }
}
輸出結果如下:

執行finally模組
1

2)try 和 catch 中都帶有 return 
public class tryDemo {
    public static int show() {
        try {
            int a = 8 / 0;
            return 1;
        } catch (Exception e) {
            return 2;
        } finally {
            System.out.println("執行finally模組");
        }
    }

    public static void main(String args[]) {
        System.out.println(show());
    }
}
輸出結果為:

執行finally模組
2

當 try 程式碼塊或者 catch 程式碼塊中有 return 時,finally 中的程式碼總會被執行,且 finally 語句 return 返回之前執行。

注意:可以使用編譯器的 Debug 功能檢視詳細過程。如果不了解如何使用 Debug 功能可參考《Java Eclipse如何偵錯程式碼》一節。

2. finally 中帶有 return

public class tryDemo {
    public static int show() {
        try {
            int a = 8 / 0;
            return 1;
        } catch (Exception e) {
            return 2;
        } finally {
            System.out.println("執行finally模組");
            return 0;
        }
    }

    public static void main(String args[]) {
        System.out.println(show());
    }
}
輸出結果如下:

執行finally模組
0

當 finally 有返回值時,會直接返回該值,不會去返回 try 程式碼塊或者 catch 程式碼塊中的返回值。

注意:finally 程式碼塊中最好不要包含 return 語句,否則程式會提前退出。

3. finally 中改變返回值

下面先來看 try 程式碼塊或者 catch 程式碼塊中的返回值是普通變數時,程式碼如下:
public class tryDemo {
    public static int show() {
        int result = 0;
        try {
            return result;
        } finally {
            System.out.println("執行finally模組");
            result = 1;
        }
    }

    public static void main(String args[]) {
        System.out.println(show());
    }
}
輸出結果為:

執行finally模組
0

由輸出結果可以看出,在 finally 程式碼塊中改變返回值並不會改變最後返回的內容。

當返回值型別是參照型別時,結果也是一樣的,程式碼如下:
public class tryDemo {
    public static Object show() {
        Object obj = new Object();
        try {
            return obj;
        } finally {
            System.out.println("執行finally模組");
            obj = null;
        }
    }

    public static void main(String args[]) {
        System.out.println(show());
    }
}
輸出結果為:

執行finally模組
[email protected]

當 try 程式碼塊或 catch 程式碼塊中的 return 返回值型別為普通變數或參照變數時,即使在後面 finally 程式碼塊中對返回值的變數重新賦值,也不會影響最後返回的值。

總結為以下幾條:
  • 當 try 程式碼塊和 catch 程式碼塊中有 return 語句時,finally 仍然會被執行。
  • 執行 try 程式碼塊或 catch 程式碼塊中的 return 語句之前,都會先執行 finally 語句。
  • 無論在 finally 程式碼塊中是否修改返回值,返回值都不會改變,仍然是執行 finally 程式碼塊之前的值。
  • finally 程式碼塊中的 return 語句一定會執行。