大家面試的時候想必會遇到這種面試題,要我們輸出結果。。。
其實在實際的業務中呢一般都是用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都會對目前方法的傳回值産生影響!