l

2013年11月13日 星期三

Java的try、catch、finally(2):Java SE 7之後

Nov. 6 22:00~23:55

image

 

Java SE 7之後

Java SE 7之後多了幾個新的功能,先看第一個叫做multi-catch exceptions,可以在一個catch block裡面同時捕捉多個例外,如下圖57行所示。Multi-catch exceptions的好處,就是當不同的例外型態,都適用相同的處理方式的時候,就可以避免在不同的catch block出現重複程式碼的問題。

image_thumb[6]

***

第二個特性叫做try-with-resources,這個功能應該是Java從C#那裡「借用」過來的。在Java SE 7之前,釋放資源的程式碼要寫在finally block裡面。如下圖所示,try block裡面用到fis、reader這兩個I/O物件,因此在finally block需要做cleanup的動作。為了歸還這兩個物件所代表的資源,finally block變得有點小複雜(75~88行)。

螢幕快照 2013-11-06 下午10.24.00

 

Java SE 7之後,可以把產生資源的程式碼寫在try ( ... )敘述裡面,如下圖中第57~58行程式碼所示。如此一來,在離開整個try statement之前,JVM會自動呼叫fis與reader物件的close() method以執行cleanup動作。

螢幕快照 2013-11-12 下午5.32.37

 

看到這裡鄉民們應該會有以下疑問:「是不是不管什麼型別的物件,只要它的instance是在try clause裡面產生的,就可以自動被清理回收?JVM怎麼知道離開try statement之前要如何執行cleanup的動作?」答案很簡單,如果鄉民們希望自己的類別要具備上述這種離開try statement之後自動cleanup的能力,就必須要讓該類別實作AutoCloseable這個Java SE 7之後才新增的介面。該介面很簡單,只有一個method:void close() throws Exception

***

最後要介紹一個一般人可能不太會注意到也不太會用到,關於重丟例外(rethrow)的改變。下列程式在Java SE 7之前是無法編譯。在rethrow() method的try block裡面,丟出一個IOException。這個IOException被第11行的catch(Exception e)給捕捉住,然後經過一番處理之後,被15行的程式碼將捕捉下來的例外原封不動的往外丟。由於例外被catch(Exception e)給捕捉住,Java SE 7 之前的編譯器會認為這個被捕捉到的例外型態屬於Exception,既然要把它往外丟,就應該在rethrow() method宣告throws Exception而非throws IOException。

螢幕快照 2013-11-06 下午10.55.13

Java SE 7之後的編譯器變得比較聰明一些,會自動判斷catch(Exception e)所捕捉到的例外型態,其實是try block裡面所丟出來的IOException,所以同樣的程式在Java SE 7之後是可以通過編譯的。

螢幕快照 2013-11-06 下午11.49.40

***

友藏內心獨白:故事鋪成完畢,下一集要講重點了。

沒有留言:

張貼留言