在Sun Tutorial中有這樣一句話:The finally
block always executes when the try
block exits. This ensures that the finally
block is executed even if an unexpected exception occurs. 看來finally塊中的語句應該是總會執行的。
先來寫一個最常見的寫法:
public class Test {<br />public static void main(String[] args) {<br />try {<br />System.out.println(args[0]);<br />System.out.println("I'm nomal");<br />} catch (Exception ex) {<br />System.out.println("I'm exception");<br />} finally {<br />System.out.println("I'm finally.");<br />}<br />}<br />}
運行這段代碼,很明顯,不論是否有參考輸入,"I'm finally."這句話都會列印出來。這是最常用的寫法,很顯然與Tutorial中的說明是相符的。
下面我們再進一步想一下,假如在try或是catch塊中使用了return語句,那麼會怎麼樣呢?
我們將代碼稍做修改:
public class Test {<br />public static void main(String[] args) {<br />try {<br />System.out.println(args[0]);<br />System.out.println("I'm nomal");<br /> return;<br />} catch (Exception ex) {<br />System.out.println("I'm exception");<br /> return;<br />} finally {<br />System.out.println("I'm finally.");<br />}<br />}<br />}
代碼的修改很簡單,只是在try和catch塊的結束位置分別加了一個return語句。
這樣運行結果是什麼呢?可能會有兩種猜想了,或是直接退出,或是仍會列印"I'm finally."。驗證真理的方法是實踐,我們運行這段代碼,看一下結果:
>java Test<br />I'm exception<br />I'm finally.</p><p>>java Test hello<br />hello<br />I'm nomal<br />I'm finally.
上面分別是輸入和不輸入參數時啟動並執行結果,很明顯,finally中的代碼還是執行了。那是不是說try和catch塊中的return語句並不起作用嗎?我們再次簡單修改代碼:
public class Test {<br />public static void main(String[] args) {<br />try {<br />System.out.println(args[0]);<br />System.out.println("I'm nomal");<br /> return;<br />} catch (Exception ex) {<br />System.out.println("I'm exception");<br /> return;<br />} finally {<br />System.out.println("I'm finally.");<br />}<br /> System.out.println("Out of try.");<br />}<br />}
在try語句外面再加入一名列印代碼,再次編譯。
編譯錯誤,結果如下:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:<br />Unreachable code
提示代碼不可達,看來return還是有用的,只是在退出方法呼叫之前,會先去執行finally中的代碼。
現在似乎說明了另外一個問題,是不是return語句還不夠厲害,“讓暴風雨來的更猛烈些吧”,我們再次修改代碼,將return語句修改成System.exit(),看一下執行結果。
public class Test {<br />public static void main(String[] args) {<br />try {<br />System.out.println(args[0]);<br />System.out.println("I'm nomal");<br /> System.exit(0);<br />} catch (Exception ex) {<br />System.out.println("I'm exception");<br /> System.exit(0);<br />} finally {<br />System.out.println("I'm finally.");<br />}<br />}<br />}
運行代碼,終於,"I'm finally."不見了。
為什麼System.exit()有這麼強大的力量呢,讓我們看一下API中的說明:exit(int status): Terminates the currently running Java Virtual Machine。原來是這樣,JVM都被終止掉了,當然不會再執行finally中的語句了。
下面是我們的結論:
在不終止VM的情況下,finally中的代碼一定會執行。
上一篇:Java牛角尖【012】: JDBC開發時為什麼要用Class.forName("")