Java高概率面試題目—finally(看完這篇文章,唬住面試官)

 

Java高概率面試題目—finally(看完這篇文章,唬住面試官)

在Java面試中關於finally的面試題目出現的概率非常高,而且一旦面試官問起絕不會是蜻蜓點水,而是會向你發起層層遞進地“連環問”,並且回答這系列問題常常需要代碼的輔助,可謂考驗基礎的面試利題。究竟面試官會問些什麼呢?應試者又該怎樣完美回答呢?今天小編就帶著猿猿們親身體驗一場finally面試,希望對你有幫助。

前提需要了解:當發生異常之後,異常之後的代碼不會執行,會到catch塊中執行,但是catch之後的代碼會執行,簡單的例子:

 public static String test(){
try {
int i=1/0;
System.out.println("error open");//上面發生異常,所以永遠不會走這裡
return "1";
} catch (ArithmeticException e) {
System.out.println("error");
}
System.out.println("try..catch...finish");
return "finish";
}

結果:

error

try..catch...finish

面試官題目

什麼時候用到finally呢?finally語句在try或catch中的return語句執行之後,還是return返回之前執行呢?

考點分析

這個題目也是考查異常相關的。對於這個題目,我們通過代碼來驗證我們的答案,因為有異議的知識點,代碼是最有說服力的。對於編程,希望你記住“不與人爭辯,一切用代碼說話”。

回答

什麼時候用到finally呢?

某些事物(除內存外)在異常處理完後需要恢復到原始狀態,如:開啟的文件,網絡連接等。

finally語句在try或catch中的return語句執行之後,還是return返回之前執行呢?

這個問題是一個很經典的問題,經常被面試官問,如果自己不去實驗一下,可能判斷就會出錯。我們結合代碼來分析一下。

下面我們通過4個demo來得出最終結論。

1

private static int test1() {

int i = 1;

try {

System.out.println("try...");

return i += 10;

} catch (Exception e) {

System.out.println("catch...");

} finally {

i++;

System.out.println("finally...");

System.out.println("i=" + i);

}

return i;

}

執行結果:

try...

finally...

i=12

test1:11

總結:finally代碼塊是在try代碼塊中的return語句執行之後,返回之前執行的。

2

private static int test2() {

int i = 1;

try {

System.out.println("try...");

return i += 10;

} catch (Exception e) {

System.out.println("catch...");

} finally {

i++;

System.out.println("finally...");

System.out.println("i=" + i);

return i;

}

}

執行結果:

test2:12

try...

finally...

i=12

總結:finally代碼塊中的return語句覆蓋try代碼塊中的return語句。

3

private static Map test3() {

Map map = new HashMap();

map.put("KEY", "INIT");

try {

System.out.println("try...");

map.put("KEY", "TRY");

return map;

} catch (Exception e) {

System.out.println("catch...");

map.put("KEY", "CATCH");

} finally {

System.out.println("finally...");

map.put("KEY", "FINALLY");

map = null;

}

return map;

}

執行結果:

try...

FINALLY

finally...

總結: 如果finally語句中沒有return語句覆蓋返回值,那麼原來的返回值可能因為finally裡的修改而改變也可能不變。傳值類型的返回值:不變;傳址類型的返回值:會變。

這裡引入來一個新的問題,怎麼判斷一個變量是傳值還是傳址?傳值:8種基本數據類型及其包裝類,字符常量。傳址:數組和對象。

4

private static int test4() {

int i = 1;

try {

System.out.println("try...");

i = i / 0;

return i += 10;

} catch (Exception e) {

System.out.println("catch...");

return i;

} finally {

i++;

System.out.println("finally...");

System.out.println("i=" + i);

}

}

執行結果:

try...

catch...

finally...

i=2

1

總結: try代碼塊中的return語句在異常的情況下不會被執行,這樣具體返回哪個看情況;catch中的return執行情況與未發生異常時try中return的執行情況完全一樣。

  • 第五種情況:
 private int test5() {
int i = 1;
try {
System.out.println("try...");
i = i / 0;
return i += 10;
} catch (Exception e) {
System.out.println("catch...");
return i;
} finally {
i++;
System.out.println("finally...");
System.out.println("i=" + i);
return i;
}
}

try...

catch...

finally...

i=2

2

總結:finally代碼塊中的return語句覆蓋try代碼塊中的return語句。

彙總

根據上面的分析,咱們來彙總一下答案:

  1. try語句沒有被執行,如在try語句之前就返回了,這樣finally語句就不會執行;因此說明了finally語句被執行的必要而非充分條件是:相應的try語句一定被執行到。
  2. 如果在try代碼塊中執行System.exit(0)語句;那麼將終止Java虛擬機JVM,因此,finally語句也不會被執行到。
  3. finally塊的語句在try或catch中的return語句執行之後返回之前執行且finally裡的修改語句可能影響也可能不影響try或catch中return已經確定的返回值,如果返回值類型為傳址類型,則影響;傳值類型,則不影響。若finally裡也有return語句則覆蓋try或catch中的return語句直接返回。


分享到:


相關文章: