參考:
Try-with-resources in Java 7 、
try-with-resources
請注意這個機制只有java 7後才適用
繼
上篇,我們這次來看看java7的新機制(同樣是參考文章後的心得形式,若需詳細請直接連入上方參考文章連結)。
先假設下面的code:
public class TryWithResource implements AutoCloseable {
private FileInputStream _input;
public void doIt() throws WrapperException, FileNotFoundException {
_input = new FileInputStream("datasheet/file.txt");
throw new WrapperException("doIt has an Exception!!!");
}
@Override
public void close() throws IOException, WrapperException {
_input.close();
throw new WrapperException("close has an Exception!!!");
}
}
以下列方式呼叫使用:
public static void withoutTryWithResources() throws WrapperException {
TryWithResource tt = new TryWithResource();
try {
tt.doIt();
} catch (Exception ex) {
throw new WrapperException(ex);
} finally {
try {
tt.close();
} catch (IOException e) {
throw new WrapperException(e);
}
}
}
public static void main(String[] args) {
try {
withoutTryWithResources();
} catch (WrapperException wex) {
wex.printStackTrace();
}
}
會有以下結果:
Exception in thread "main" java.lang.IndexOutOfBoundsException
exception.WrapperException: close has an Exception!!!
at exception.failsave.TryWithResource.close(TryWithResource.java:12)
at exception.failsave.TryWithResource.withoutTryWithResources(TryWithResource.java:32)
at exception.failsave.TryWithResource.main(TryWithResource.java:49)
(上述的exception 行號每人都會不一樣)
執行流程如下:
- doIt()
- throw new WrapperException("doIt...")
- first catch(Exception ex) block
- finally block
- close()
- throw new WrapperException("close...")
最始祖的exception為應該為doIt()中出現的,但如同前一篇所說,始祖exception會被吃掉,因此,到了步驟6原先的始祖exception(步驟2)就消失了,這造成我們難以在第一時間發現最根本的問題點,因此我們可以使用java7的新機制,修改如下:
public static void withResources() throws WrapperException {
try (TryWithResource tt = new TryWithResource()) {
tt.doIt();
} catch (Exception e) {
throw new WrapperException(e);
}
}
public static void main(String[] args) {
try {
// withoutTryWithResources();
withResources();
} catch (WrapperException wex) {
wex.printStackTrace();
}
}
而這次的exception 顯示為:
exception.WrapperException: exception.WrapperException: doIt has an Exception!!!
at exception.failsave.TryWithResource.withResources(TryWithResource.java:43)
at exception.failsave.TryWithResource.main(TryWithResource.java:50)
Caused by: exception.WrapperException: doIt has an Exception!!!
at exception.failsave.TryWithResource.doIt(TryWithResource.java:15)
at exception.failsave.TryWithResource.withResources(TryWithResource.java:41)
... 1 more
Suppressed: exception.WrapperException: close has an Exception!!!
at exception.failsave.TryWithResource.close(TryWithResource.java:21)
at exception.failsave.TryWithResource.withResources(TryWithResource.java:42)
... 1 more
(再一次提醒,exception中的行號每人不同)
上述流程為:
- doIt()
- throw new WrapperException("doIt...")
- immediately call close()
- close()
- Suppressed:throw new WrapperException("close...")
- throw WrapperException("doIt...") (step 2)
不僅少了很多恐怖的try catch跟finally還很清楚地馬上就知道始祖exception問題處。
注意其中的
Suppressed: exception.WrapperException: close has an Exception!!!(步驟5)
由於使用了try-with-resources機制,因此後面發生在close()中的exception就會被suppress(壓制)。
而try-with-resources機制也可以同時使用多個:
private static void printFileJava7() throws IOException {
try( FileInputStream input = new FileInputStream("file.txt");
BufferedInputStream bufferedInput = new BufferedInputStream(input)
) {
int data = bufferedInput.read();
while(data != -1){
System.out.print((char) data);
data = bufferedInput.read();
}
}
}
如果發生了問題,則destructor (就是呼叫close())的順序為反向的:
- bufferedInput.close()
- input.close()
另外還有一個限制,使用在try-with-resources都必須在try(...)中宣告,而
不能使用下列方式:
private static void printFileJava7() throws IOException {
FileInputStream input = null;
BufferedInputStream bufferedInput = null;
try( input = new FileInputStream("file.txt");
bufferedInput = new BufferedInputStream(input)
) {
int data = bufferedInput.read();
while(data != -1){
System.out.print((char) data);
data = bufferedInput.read();
}
}
}
因此只要implement
AutoCloseable 這個interface,除了原生java的class以外,自己實作的class也同樣可以享受try-with-resources 的好處呢!
以後解決這種惱人的io問題總算有解了!!exception handling真是個很重要的課題阿!!該去買文章作者的kindle電子書了
Java Exception Handling
話說好便宜阿作者真是佛心來者...