1. 程式人生 > >java try finally返回值問題

java try finally返回值問題

需要知道的是:finally的語句會先於try或者catch的返回語句之前執行,如果finally中有return語句,那麼try或catch中的return語句會被finally中的return覆蓋,不建議在finally中放return

情況一:try、catch和finally中都有return

  public static void main(String[] args) {
        System.out.println(testInt());
    }
 private static int testInt(){
        int a = 0;
        try
{ return a; }catch (Exception e){ a = 9; e.printStackTrace(); return a; }finally { a = 10; return a; } }

最後輸出:
10

在try中的return執行之前,會執行finally中的語句,finally中有return,於是會覆蓋掉try中的return。如果此時發生了異常,catch中的return語句會執行嗎?看下面:

  public static void main(String[] args) {
        System.out.println(testInt());
    }
 private static int testInt(){
        int a = 0;
        try{
           int b = 7/a; //產生了異常
            return a;
        }catch (Exception e){
            a = 9;
            e.printStackTrace();
            return
a; }finally { a = 10; return a; } }

輸出結果:
10
java.lang.ArithmeticException: / by zero
at pattern.App.testInt(App.java:40)
at pattern.App.main(App.java:31)
產生了異常,catch中語句被執行,但是catch中的return執行之前會執行finally中的語句,所以catch中的return依然被覆蓋

情況二:try或者catch中有return,finally中沒有return

public static void main(String[] args) {
        System.out.println(testInt());
    }
private static int testInt(){
        int a = 0;
        try{
            return a;
        }catch (Exception e){
            a = 9;
            e.printStackTrace();
            return a;
        }finally {
           System.out.println("執行finally");
            a = 10;
        }

    }

輸出:
執行finally
0
可以看到,finally中的語句依然執行了,但是a的值在finally中改變了,返回值並沒有改變,如果這裡產生了異常呢?自然是會輸出9的(可以自己驗證一下),這裡可以看到對於基本型別a,finally的賦值並沒有改變返回值,如果是下面非基本型別的情況呢?

情況三:對於非基本型別

 public static void main(String[] args) {
        System.out.println(testNum().getNum());
    }
 private static Num testNum(){
        Num num = new Num();
        int a = 0;
        try{
            num.setNum(7);
            return num;
        }catch (Exception e){
            e.printStackTrace();
            num.setNum(9);

        }finally {
            num.setNum(10);
        }
        return num;
    }

最後輸出結果:
10

同理如果是產生了異常,結果仍然是10(可以自己驗證)
可以看到,對於非基本型別,finally中的賦值最後在return中會被返回,通過看向志明《深入理解Java虛擬機器》第187頁講解“class檔案的屬性表”的時候,找到了為什麼:

  • 不管什麼情況,finally中的語句總會執行(除非程式執行System.exit()),正常情況下載try後面執行,拋異常時載catch後面執行
  • 對於返回值問題。try(或者catch)中的return語句的返回值放入執行緒棧的頂部:如果返回值是基本型別則頂部存放的就是值,如果返回值是引用型別,則頂部存放的就是地址。finally中的return語句可以修改引用所對應的物件,無法修改基本型別。所以情況二中的基本型別finally無法修改,但是情況三可以修改
  • 不建議在finally中使用return