天天看點

try,catch,finally的執行順序問題

大家面試的時候想必會遇到這種面試題,要我們輸出結果。。。

其實在實際的業務中呢一般都是用finally來關閉流的,很少做其它業務操作,是以呢大家也就容易忽視掉這個問題

首先在finally和try中對資料的操作時資料分為 基本資料類型和引用資料類型,他們存放的地方也不一樣,一個是棧區另一個是在堆區。

首先我們對基本資料類型的結果進行分析:

1 finally 中沒有return

public class Main {
    private  static  int a=2;

    public static void main(String[] args) {

        System.out.println("test輸出的結果 "+test());
        System.out.println("main 自加後 a="+(a++));


    }
    private  static  int test(){
        try {
            a+=3;
            System.out.println("try  a="+a);
            return a;
        }catch (Exception e){

        }finally {
            ++a;
            System.out.println("finally a="+a);
        }
        return 0;

    }
}
           

輸出結果:

try  a=5

finally a=6

test輸出的結果 5

main a=6

結論: 可見方法test的傳回值不受finally中的影響,但是變量a還是受到了影響,值改變了,傳回值是存放在棧中的,return是就           已經把傳回值壓入棧了,相當于一個臨時變量。在finally中并不會影響傳回值

2 在finally 中加入 return

   ..............................

  finally {

              ++a;

              System.out.println("finally a="+a);

              return a;

           }

輸出結果:

try  a=5

finally a=6

test輸出的結果 6

main a=6

結論: 此時test方法的傳回值是6和a的值相等, 在try,catch中的傳回值可以發現被finally的傳回值給屏蔽了,是以如果finally中              有return則會屏蔽目前方法中的傳回值

現在對引用變量進行分析

1 finally中沒有return 

public class Main {
    private  static List<String> list=new ArrayList<>();

    public static void main(String[] args) {
        System.out.println("test輸出的結果 "+test());
        System.out.println("main list="+list.toString());


    }
    private  static  List test(){
        try {
            list.add("33");
            System.out.println("try  list="+list.toString());
            return list;
        }catch (Exception e){

        }finally {
            list.add("66");
            System.out.println("finally list="+list.toString());
        }
        return null;
    }
}
           

輸出結果:

try  list=[33]

finally list=[33, 66]

test輸出的結果 [33, 66]

main list=[33, 66]

結論: 通過結果可以知道 test的傳回值内容也是跟集合list一樣的, 因為list是引用類型是以堆區中存放了記憶體位址,在finally對值          進行改變時還是隻想同一個位址,隻是位址的内容變化了

2 finally中有return 、

輸出值:

try  list=[33]

finally list=[33, 66]

test輸出的結果 [33, 66]

main list=[33, 66]

結論:可見引用類型時finally有沒有return都會對目前方法的傳回值産生影響!