2012年10月9日 星期二

Java SE 7 - Exception - Suppressed 架構觀念

有時在catch或finally區段裡會再進行try…catch…相關動作,以確保所執行的程式碼如果再發生例外時應該做的對應處理。如下:

try{
    throw new Exception("Ex 1");
} catch (Exception ex){
    try{
       Do Something….
       throw new Exception("Ex 2");
    } catch (Exception ex2){
       Do Something…
    }
    throw ex;
}


try{
    throw new Exception("Ex 1");
} catch (Exception ex){
    Do Something….
    throw ex;
} finally {
    try{
       Do Something….
       throw new Exception("Ex 2");
    } catch (Exception ex2){
       Do Something…
    }
}

通常上述範例只會呈現Ex 1訊息如下
Exception in thread "main" java.lang.Exception: Ex 1
    ……


如果要完整呈現Ex 2的錯誤則必須直接列出:
try{
    throw new Exception("Ex 1");
} catch (Exception ex){
    try{
       Do Something….
       throw new Exception("Ex 2");
    } catch (Exception ex2){
       ex2.printStackTrace();
    }
    throw ex;
}

但會呈現兩則訊息
java.lang.Exception: Ex 2
    ......
Exception in thread "main" java.lang.Exception: Ex 1
    ......

如果連Ex 2都拋出
try{
    throw new Exception("Ex 1");
} catch (Exception ex){
    Do Something….
    throw ex;
} finally {
    try{
       Do Something….
       throw new Exception("Ex 2");
    } catch (Exception ex2){
       throw ex2;
    }
}
則只會呈現ex2
Exception in thread "main" java.lang.Exception: Ex 2
      …...

SE 7多出了Exception Suppressed抑制功能,讓我們先看寫法與結果:
try{
    throw new Exception("Ex 1");
} catch (Exception ex){
    try{
       throw new Exception("Ex 2");
    } catch (Exception ex2){
       ex.addSuppressed(ex2);
    }
    throw ex;
}

Exception outex = null;
try{
   throw new Exception("Ex 1");
} catch (Exception ex){
   outex = ex;
   throw ex;
} finally {
   try{
      throw new Exception("Ex 2");
   } catch (Exception ex2){
      outex.addSuppressed(ex2);
   }
}
這個時候Ex 2會被包在Ex 1裡呈現,可以讓我們很清楚的知道錯誤的結構與內容:
Exception in thread "main" java.lang.Exception: Ex 1
    ......
    Suppressed: java.lang.Exception: Ex 2
        ......
        ... 1 more

這樣的寫法在實作java.lang.AutoCloseable Inteface的類別中,Java編譯器會將其轉成這樣的寫法:

public static void main(String[] args) throws Exception {
    test();
}
static class ResourceA implements AutoCloseable {
    public void read() throws Exception{
        throw new Exception("ResourceA read exception");
    }
    @Override
    public void close() throws Exception {
        throw new Exception("ResourceA close exception");
    }
};
public static void test() throws Exception{
    try (ResourceA a = new ResourceA()) {
       a.read();
    } catch (Exception e) {
       throw e;
    }
}

呈現訊息如下:
Exception in thread "main" java.lang.Exception: ResourceA read exception
    ......
    Suppressed: java.lang.Exception: ResourceA close exception
        ......
        ... 1 more
待續...

轉貼請註明出處,最好直接使用聯結轉貼!Thanks~
作者: Samuel
日期:2012/10/06


沒有留言:

張貼留言