<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-204  評論-149  文章-0  trackbacks-0

    Java 提供了兩種Exception 的模式,一種是執(zhí)行的時候所產(chǎn)生的Exception (Runtime Exception),另外一種則是受控制的Exception (Checked Exception)。

    所有的Checked Exception 均從java.lang.Exception 繼承而來,而Runtime Exception 則繼承java.lang.RuntimeException 或java.lang.Error (實際上java.lang.RuntimeException 的上一層也是java.lang.Exception,這說明作為exception兩者并沒有本質(zhì)的區(qū)別,只是java語言本身從功能考慮有所區(qū)分,這才導(dǎo)致下面提到的不同點)。

    一個函數(shù)如果會拋出Checked Exception ,(這里包含兩種情況,一個是函數(shù)本身拋出,另外一種是它調(diào)用的函數(shù)會拋出Checked Exception 但是它并沒有去catch這個exception),那在聲明此函數(shù)的時候必須標(biāo)明throws XXXException()。而Runtime Exception不需要如此聲明。

    邏輯上看,Runtime Exception 與Checked Exception 使用目的不一樣。一般而言,Checked Exception 表示這個Exception 必須要被處理,也就是說程序設(shè)計者應(yīng)該已經(jīng)知道可能會收到某個Exception(因為要try catch住) ,所以程序設(shè)計者應(yīng)該能也必須(或者標(biāo)明throws XXXException()繼續(xù)拋出去,或者try catch處理,不然是編譯不過的)針對這些不同的Checked Exception 做出不同的處理。而Runtime Exception 通常會暗示著程序上的錯誤,這種錯誤會導(dǎo)致程序設(shè)計者無法處理,而造成程序無法繼續(xù)執(zhí)行下去(可以try catch處理而避免程序掛掉,但是這常常會掩蓋問題所在)。


    checked exception由于必須被處理,會給程序員帶來額外的麻煩,試想一個函數(shù)a,它會調(diào)用到b1,b2...,b9一共9個函數(shù),這些函數(shù)每個都會拋出checked exception,而a函數(shù)里面又沒有辦法處理這些exception,那在聲明a函數(shù)的時候就必須連寫9個throw xxxException,夠累的!!然而這僅僅是問題的一個方面,所以下面這篇文章試圖說服我們盡量使用runtime exception替代checked exception(前面提到可以try catch處理runtime exception,而避免程序掛掉,這也是這樣做的一個前提)。

    這篇文章指出了Java中checked Exception的一些缺點,提出應(yīng)該在程序設(shè)計中避免使用checked Exception,對于需要處理checked Exception的代碼,可以使用ExceptionAdapter這個類對checked Exception進(jìn)行包裝。這篇文章的概念和ExceptionAdapter這個類均源自Bruce Eckel的Does Java need Checked Exception。


    Java
    Exception分為兩類,一類是RuntimeException及其子類,另外一類就是checked ExceptionJava要求函數(shù)對沒有被catch處理掉的checked Exception,需要將其寫在函數(shù)的聲明部分。然而,這一要求常常給程序員帶來一些不必要的負(fù)擔(dān)。

    為了避免在函數(shù)聲明中寫throws部分,在Java項目里面常常可以看到以下代碼用來‘吞掉’Exception

     try {
      
    // 
     }
     catch (Exception ex) {
               ex.printStackTrace();
      }


    這顯然不是一個好的處理Exception辦法,事實上,catch并處理一個Exception意味著讓程序從發(fā)生的錯誤(Exception)中恢復(fù)過來。從這種意義上說,已上的代碼只可能在一些很簡單的情況下工作而不帶來問題。

    對于很多Exception,往往沒有去處理它并讓程序從錯誤中恢復(fù)出來的辦法,這時唯一能做的事情可能就是在界面上顯示一些提示信息給用戶。這種情況下讓程序拋出遇到的Exception是更為合理的做法。然而,這樣做會使得一些函數(shù)的聲明急劇膨脹。一個函數(shù)可能需要聲明會拋出的78checked Exception,而且每個調(diào)用它的函數(shù)也需要同樣的聲明。

    比這更糟糕的是,這有可能破壞類設(shè)計的open-close原則。簡單來說,open-close原則是指當(dāng)擴(kuò)展一個模塊的時候,可以不影響其現(xiàn)有的clientopen-close原則是通過繼承來實現(xiàn)的,當(dāng)繼承一個類的時候,我們既擴(kuò)展了這個類,也不會影響原有的client(因為對這個類沒有改動)。

    現(xiàn)在考慮下面這種情況,有一個父類Base

     

    public class Base {
        
    public void foo() throws ExceptionA {
           
    // 
        }

    }

     

     

    現(xiàn)在需要繼承Base這個類并重載foo這個方法,在新的實現(xiàn)中,foo可能拋出ExceptionB

    public class Extend extends Base {
        
    public void foo() throws ExceptionB {
           
    // 
        }

    }

     


    然而,這樣寫在Java里面是不合法的,盡管Java不會拋出的Exception看作函數(shù)特征的一部分,但子類聲明拋出的Exception必須是父類的子集。
    可以在Base類的foo方法中加入拋出ExceptionB的聲明,然而,這樣就破壞了open-close原則。而且,有時我們沒有辦法去修改父類,比如當(dāng)重載一個Jdk里的類的時候。

    另一個可能的做法是在Extendfoo方法中catchExceptionB,然后構(gòu)造一個ExceptionA并拋出。這是個可行的辦法但也只是一個權(quán)宜之計。

    如果使用RuntimeException,這些問題都不會存在。這說明checked Exception并不是一個很實用的概念,也意味著在程序設(shè)計的時候,我們應(yīng)該讓自己的Exception類繼承RuntimeException而不是Exception。(這和JDK的建議正好相反,但實踐證明這樣做代碼的質(zhì)量更好。)

    對于那些需要處理checked Exception的代碼,可以利用一個ExceptionAdapter的類把checked Exception包裝成一個RuntimeException拋出。ExceptionAdapter來自Bruce EckelDoes Java need Checked Exception這篇文章,

    public class ExceptionAdapter extends RuntimeException {

        
    public ExceptionAdapter(Exception ex) {

           
    super(ex);

        }


        
    public void printStackTrace(java.io.PrintStream s) 

           getCause().printStackTrace(s); 

        }


        
    public void printStackTrace(java.io.PrintWriter s) 
           getCause().printStackTrace(s);

        }


        
    // rethrow()的作用是把被包裝的Exception再次拋出。

        
    public void rethrow() 
           
    throws Exception
        
    {
           
    throw (Exception) getCause();
        }

    }


    posted on 2009-06-20 15:49 Frank_Fang 閱讀(396) 評論(0)  編輯  收藏 所屬分類: Java編程
    主站蜘蛛池模板: 二区久久国产乱子伦免费精品| 99久久国产免费中文无字幕| 久久精品国产亚洲Aⅴ蜜臀色欲| 丝袜足液精子免费视频| 亚洲婷婷综合色高清在线| 国产精品二区三区免费播放心| a级成人免费毛片完整版| 亚洲中文字幕无码中文字| 亚洲综合熟女久久久30p| 99久久免费国产精品特黄| 羞羞视频在线观看免费| 亚洲经典在线中文字幕| 亚洲AV日韩精品久久久久久 | 91热成人精品国产免费| 亚洲第一se情网站| 亚洲人成在线影院| 免费一级毛片在级播放| 精品久久8x国产免费观看| 理论片在线观看免费| 亚洲欧洲日韩综合| 综合亚洲伊人午夜网 | 久久aa毛片免费播放嗯啊| 亚洲暴爽av人人爽日日碰| 久久精品亚洲日本佐佐木明希| 日韩成人在线免费视频| 亚洲香蕉免费有线视频| 香蕉免费一级视频在线观看| 亚洲经典千人经典日产| 亚洲精品视频免费在线观看| 三上悠亚亚洲一区高清| 成人五级毛片免费播放| 5555在线播放免费播放| 国产男女爽爽爽免费视频| AV激情亚洲男人的天堂国语| 亚洲六月丁香六月婷婷色伊人 | 亚洲AV无码久久精品蜜桃| 亚洲中文字幕成人在线| 日韩精品视频免费在线观看| 1000部无遮挡拍拍拍免费视频观看| aa在线免费观看| 一出一进一爽一粗一大视频免费的|