Java try catch finally 總結

Frank範發表於2018-04-14

題記:

網上看了很多try catch finally 的例子,發現並沒有一個總結的非常全的,將各種case都有寫的,所以在這裡總結下,不正確的還請指教!

問題1: finally 語句內一定會執行嗎?

不一定會執行:如下兩種情況

  1. finally 語句必須在try語句塊執行的情況下才會執行。
  2. 如果有System.exit()語句,終止了JVM,則不會執行。舉例:
public int testCas1() {
        int i = 1;
        if (i == 1) {
            return 0;
        }
        try {
            System.out.println("try block");// 不會執行
            return i;
        } finally {
            System.out.println("finally block");
        }
    }

返回結果:0,finally 中內容不會列印。

問題2: finally 語句如果有return,會影響return結果嗎?

會影響,會return成finally 中要return的結果

public int test() {
        int i = 1;
        try {
            System.out.println("try block " + i);
            i = i / 0;
            return i;
        } catch (Exception e) {
            System.out.println("catch block");
            i = i +1;
            return i;
        }
        finally {
            i = i + 1;
            System.out.println("finally block");
            return i;
        }
    }

test 結果如下,分析:即使出現exception 也會執行到finally.

try block 1
catch block
finally block
return value of test(): 3

問題3: finally 語句沒有return,但是修改了要返回的值,會最終影響返回結果嗎?

  1. 如果return的資料是基本資料型別或文字字串,則在finally中對該基本資料的改變不起作用,try中的return語句依然會返回進入finally塊之前保留的值。
  2. 如果return的資料是引用資料型別,而在finally中對該引用資料型別的屬性值的改變起作用,try中的return語句返回的就是在finally中改變後的該屬性的值。
public int test() {
        int i = 1;
        try {
            System.out.println("try block " + i);
            i = i / 0;
            return i;
        } catch (Exception e) {
            System.out.println("catch block");
            i = i +1;
            return i;
        }
        finally {
            i = i + 1;
            System.out.println("finally block");
        }
    }

結果, return 是2 不是3

try block 1

catch block

finally block

return value of test(): 2

引用型別:

public static Person test() {
        Person result = new Person();
        try {
            result.age = 30;
            return result;
        } finally {
            result.age = 50;
        }
    }
    public static class Person{
        public static int age;
    }

結果:Person.age = 50;

如果沒有異常出現,而且finally語句中沒有return,則會執行try裡邊的return,並且,會將變數暫存起來(物件存的是引用的地址),再去執行finally中的語句,這時候,如果返回值是基本資料型別或者字串,則finally相當於更改副本,不會對暫存值有影響;但是,如果返回值是物件,則finally中的語句,仍會根據地址的副本,改變原物件的值。所以上邊的例子,返回值的age為50。


相信通過以上3個問題,應該比較能駕馭對finally的各種題目。



相關文章