通用的異常類的設計

          在設計一個新的異常類時,首先看看是否真正的需要這個異常類。一般情況下盡量不要去設計新的異常類,而是盡量使用java中已經存在的異常類。

          如:IllegalArgumentException, UnsupportedOperationException等。

          不管是新的異常是chekced異常還是unChecked異常。我們都必須考慮異常的嵌套問題。

          比如:

          1 public void methodA() throws ExceptionA{  
          2 
          3                  
          4 
          5         throw new ExceptionA();       
          6 
          7     }

          方法methodA聲明會拋出ExceptionA.

          public void methodB() throws ExceptionB

          methodB聲明會拋出ExceptionB,當在methodB方法中調用methodA時,ExceptionA是無法處理的,所以ExceptionA應該繼續往上拋出。一個辦法是把methodB聲明會拋出 ExceptionA,但這樣已經改變了MethodB的方法簽名。一旦改變,則所有調用methodB的方法都要進行改變。另一個辦法是把ExceptionA封裝成ExceptionB,然后再拋出。如果我們不把ExceptionA封裝在ExceptionB中,就丟失了根異常信息,使得無法跟蹤異常的原始出處。

          代碼如下:

           

           1 public void methodB()throws ExceptionB{  
           2 
           3           try{  
           4 
           5               methodA();  
           6 
           7                
           8 
           9            }    catch(ExceptionA ex){  
          10 
          11               throw new ExceptionB(ex);  
          12 
          13             }  
          14 
          15         }

          ExceptionB嵌套一個ExceptionA,我們暫且把ExceptionA稱為“起因異常”,因為ExceptionA導致了ExceptionB的產生,這樣才不使異常信息丟失。所以我們在定義一個新的異常類時,必須提供這樣一個可以包含嵌套異常的構造函數,并有一個私有成員來保存這個“起因異常”。

          代碼如下:

            

          1 public Class ExceptionB extends Exception{  
           2 
           3         private Throwable cause;  
           4 
           5            
           6 
           7         public ExceptionB(String msg, Throwable ex){  
           8 
           9             super(msg);  
          10 
          11             this.cause = ex;  
          12 
          13         }  
          14 
          15            
          16 
          17         public ExceptionB(String msg){  
          18 
          19             super(msg);  
          20 
          21         }  
          22 
          23        
          24 
          25         public ExceptionB(Throwable ex){  
          26 
          27             this.cause = ex;  
          28 
          29         }  
          30 
          31     }

          當然,我們在調用printStackTrace方法時,需要把所有的“起因異常”的信息也同時打印出來。所以我們需要覆寫printStackTrace方法來顯示全部的異常棧跟蹤。包括嵌套異常的棧跟蹤。

          代碼如下:

           1 public void printStackTrace(PrintStrean ps){  
           2 
           3         if(cause == null){  
           4 
           5             super.printStackTrace(ps);  
           6 
           7         }else{  
           8 
           9             ps.println(this);  
          10 
          11             cause.printStackTrace(ps);  
          12 
          13         }  
          14 
          15     }  

          一個完整的支持嵌套的checked異常類源碼如下。我們在這里暫且把它叫做NestedException

           1 public class NestedException extends Exception {
           2 
           3     private Throwable cause;
           4 
           5     public NestedException(String msg) {
           6 
           7         super(msg);
           8 
           9     }
          10 
          11     public NestedException(String msg, Throwable ex) {
          12 
          13         super(msg);
          14 
          15         this.cause = ex;
          16 
          17     }
          18 
          19     public Throwable getCause() {
          20 
          21         return (this.cause == null ? this : this.cause);
          22 
          23     }
          24 
          25     public getMessage() {
          26 
          27         String message = super.getMessage();
          28 
          29         Throwable cause = getCause();
          30 
          31         if (cause != null) {
          32 
          33             message = message + ";nested Exception is " + cause;
          34 
          35         }
          36 
          37         return message;
          38 
          39     }
          40 
          41     public void printStackTrace(PrintStream ps) {
          42 
          43         if (getCause == null) {
          44 
          45             super.printStackTrace(ps);
          46 
          47         } else {
          48 
          49             ps.println(this);
          50 
          51             getCause().printStackTrace(ps);
          52 
          53         }
          54 
          55     }
          56 
          57     publicvoid printStackTrace(PrintWrite pw) {
          58 
          59         if (getCause() == null) {
          60 
          61             super.printStackTrace(pw);
          62 
          63         } else {
          64 
          65             pw.println(this);
          66 
          67             getCause().printStackTrace(pw);
          68 
          69         }
          70 
          71     }
          72 
          73     public void printStackTrace() {
          74 
          75         printStackTrace(System.error);
          76 
          77     }
          78 
          79 }
          80 
          81 

          同樣要設計一個unChecked異常類也與上面一樣。只是需要繼承RuntimeException

          可以參看一些開源框架中的一些通用的異常的設計,比如Spirng中的NestedCheckedExceptionIbatis中的NestedException等,了解更多異常的設計和處理的信息。

          posted on 2008-05-07 17:30 云淡風清 閱讀(674) 評論(0)  編輯  收藏 所屬分類: Java


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2008年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          導航

          統計

          常用鏈接

          留言簿(1)

          隨筆分類(15)

          隨筆檔案(15)

          收藏夾(1)

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 肃宁县| 额尔古纳市| 平果县| 台北市| 大余县| 鹤岗市| 中江县| 伊川县| 施甸县| 灵璧县| 三亚市| 屯昌县| 探索| 壶关县| 翁牛特旗| 邵武市| 镇赉县| 乐平市| 彰武县| 阜城县| 周至县| 花垣县| 宜兴市| 孟村| 乃东县| 鄂州市| 秀山| 株洲县| 北京市| 宁乡县| 张掖市| 元朗区| 凭祥市| 民丰县| 黄梅县| 海南省| 平阳县| 兰溪市| 梁山县| 兴国县| 原阳县|