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

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

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

    Java語(yǔ)法總結(jié) - 異常

    軟件開(kāi)發(fā)中一個(gè)古老的說(shuō)法是:80%的工作使用20%的時(shí)間。80%是指檢查和處理錯(cuò)誤所付出的努力。在許多語(yǔ)言中,編寫(xiě)檢查和處理錯(cuò)誤的程序代碼很乏味,并使應(yīng)用程序代碼變得冗長(zhǎng)。原因之一就是它們的錯(cuò)誤處理方式不是語(yǔ)言的一部分。盡管如此,錯(cuò)誤檢測(cè)和處理仍然是任何健壯應(yīng)用程序最重要的組成部分。

    Java提供了一種很好的機(jī)制,用強(qiáng)制規(guī)定的形式來(lái)消除錯(cuò)誤處理過(guò)程中隨心所欲的因素:異常處理。它的優(yōu)秀之處在于不用編寫(xiě)特殊代碼檢測(cè)返回值就能很容易地檢測(cè)錯(cuò)誤。而且它讓我們把異常處理代碼明確地與異常產(chǎn)生代碼分開(kāi),代碼變得更有條理。異常處理也是Java中唯一正式的錯(cuò)誤報(bào)告機(jī)制。

    第一部分    異常

    1、拋出異常。所有的標(biāo)準(zhǔn)異常類都有兩個(gè)構(gòu)造器:一個(gè)是缺省構(gòu)造器,一個(gè)是帶參數(shù)的構(gòu)造器,以便把相關(guān)信息放入異常對(duì)象中。
        throw new NullPointerException();
        throw new NullPointerException("t = null");

    2、如果有一個(gè)或者多個(gè)catch塊,則它們必須緊跟在try塊之后,而且這些catch塊必須互相緊跟著,不能有其他任何代碼。C++沒(méi)有這樣的限制,所以C++的異常處理處理不好就會(huì)寫(xiě)得很亂,拋來(lái)拋去的。

    3、使用try塊把可能出現(xiàn)異常的代碼包含在其中,這么做的好處是:處理某種指定的異常的代碼,只需編寫(xiě)一次。作業(yè)沒(méi)寫(xiě)完的同學(xué)到走廊罰站去,這符合我們處理問(wèn)題的方式,不用挨個(gè)地告訴。

    4、無(wú)論是否拋出異常,finally塊封裝的代碼總能夠在try塊之后的某點(diǎn)執(zhí)行。
    例子:
        try {
            return ;    
        }
        finally{
            System.out.print("You can't jump out of my hand!");    
        }

    甚至你在try塊內(nèi)用return語(yǔ)句想跳過(guò)去都不可以!finally內(nèi)的輸出語(yǔ)句還是執(zhí)行了!別想逃出我的手掌心!

    5、catch塊和finally塊是可選的,你可以只使用try。但是這么做有意思嗎?

    6、推卸責(zé)任。Java允許你推卸責(zé)任,沒(méi)有必要從相應(yīng)的try塊為每個(gè)可能的異常都編寫(xiě)catch子句。Java2類庫(kù)中很多方法都會(huì)拋出異常,就是是把異常處理的權(quán)限交給了我們用戶。畢竟,Java不知道你的自行車(chē)被偷了之后,你會(huì)去報(bào)案還是會(huì)忍氣吞聲自認(rèn)倒霉,或者偷別人的自行車(chē)。我們需要這種處理異常的自由度。

    7、調(diào)用棧。調(diào)用棧是程序執(zhí)行以訪問(wèn)當(dāng)前方法的方法鏈。被調(diào)用的最后一個(gè)方法在棧的頂部,它將被最先執(zhí)行完畢,然后彈出;第一個(gè)調(diào)用方法位于底部,也就是main函數(shù)。在catch子句中使用printStackTrace()方法打調(diào)用棧信息是比較常用的定位異常的方法。printStackTrace()繼承自Throwable。

    8、異常的傳播。在一個(gè)方法A中,如果一個(gè)異常沒(méi)有得到處理,它就會(huì)被自動(dòng)拋到調(diào)用A方法的B方法中。如果B方法也沒(méi)有處理這個(gè)異常,他就會(huì)被繼續(xù)依次向上拋,直到main方法。如果main也沒(méi)有理會(huì)它,那么異常將導(dǎo)致JVM停止,程序就中止了。你被同學(xué)揍了,先去告訴老師。老師不理你你就去告訴教導(dǎo)處主任,教導(dǎo)處主任也不管那只能告訴校長(zhǎng),校長(zhǎng)還不管!沒(méi)有比他更大的了,于是你崩潰了,學(xué)業(yè)中止了……下面這段程序記錄了悲慘的輟學(xué)歷史:
        class ExceptionDemo {
            static void student() throws Exception{
                teacher();
            }
            static void teacher() throws Exception{
                schoolmaster();
            }
            static void schoolmaster() throws Exception{
                throw new Exception();
            }
            public static void main(String[] args) {
                try {
                student();
            }
            catch (Exception e) {
                e.printStackTrace();
            }         
            }
        }
    輸出結(jié)果是:
    java.lang.Exception
        at ExceptionDemo.schoolmaster(ExceptionDemo.java:9)
        at ExceptionDemo.teacher(ExceptionDemo.java:6)
        at ExceptionDemo.student(ExceptionDemo.java:3)
        at ExceptionDemo.main(ExceptionDemo.java:13)
    可以看出函數(shù)的調(diào)用棧,一級(jí)一級(jí)地哭訴……

    9、異常的層次結(jié)構(gòu)及Error。
            Object
            Throwable
        Error        Exception
    Throwable繼承自O(shè)bject,Error和Exception繼承自Throwable。Error比較特殊,它對(duì)應(yīng)于我們常說(shuō)的不可抗拒的外力,房屋中介的合同上總有一條,如遇不可抗拒的外力本合同中止,返還乙方押金。我不安地問(wèn):不可抗拒的外力指什么?中介回答:比如戰(zhàn)爭(zhēng)、彗星撞擊地球等。對(duì)Java來(lái)說(shuō)Error是指JVM內(nèi)存耗盡等這類不是程序錯(cuò)誤或者其他事情引起的特殊情況。一般地,程序不能從Error中恢復(fù),因此你可以能眼睜睜地看著程序崩潰而不必責(zé)怪自己。嚴(yán)格來(lái)講,Error不是異常,因?yàn)樗皇抢^承自Exception。

    10、誰(shuí)之錯(cuò)?一般地,異常不是我們程序員的錯(cuò),不是程序設(shè)計(jì)上的缺陷。比如讀取一個(gè)重要文件,這個(gè)文件被用戶誤刪了;正上著網(wǎng)呢,網(wǎng)線被用戶的寵物咬斷了。為了程序的健壯性,我們盡量考慮出現(xiàn)可能性大的異常,并處理,但我們不能窮盡。

    11、異常的捕獲之一。catch子句的參數(shù)是某種類型異常的對(duì)象,如果拋出的異常是該參數(shù)的子類,那么這個(gè)異常將被它捕獲。也就是說(shuō)被拋出的異常不會(huì)精確地尋找最匹配的捕獲者(catch子句),只要是它的繼承結(jié)構(gòu)的直系上層就可以捕獲它。

    按照這個(gè)邏輯,catch(Exception e) 不就能捕獲所有的異常嗎?事實(shí)上,確實(shí)如此。 但是一般地,不建議使用這種一站式的異常處理。因?yàn)檫@樣就丟失了具體的異常信息,不能為某個(gè)具體的異常編寫(xiě)相應(yīng)的異常處理代碼,失去了異常處理的意義。從哲學(xué)角度來(lái)講,具體問(wèn)題要具體分析,能治百病的萬(wàn)能藥一般都是無(wú)效的保健品。

    Java在此處為什么這么設(shè)計(jì)呢?因?yàn)橛辛硪环N機(jī)制的存在,請(qǐng)看下條分解。

    12、異常的捕獲之二。當(dāng)拋出一個(gè)異常時(shí),Java試圖尋找一個(gè)能捕獲它的catch子句,如果沒(méi)找到就會(huì)沿著棧向下傳播。這個(gè)過(guò)程就是異常匹配。Java規(guī)定:最具體的異常處理程序必須總是放在更普通異常處理程序的前面。這條規(guī)定再合理不過(guò)了,試想如果把catch(Exception e)放在最上面,那么下面的catch子句豈不是永遠(yuǎn)不能執(zhí)行了?如果你非要把更普遍的異常處理放在前面,對(duì)不起,通不過(guò)編譯!雖然編譯器不會(huì)這樣報(bào)錯(cuò):“It is so stupid to do like that!”……

    13、捕獲或聲明規(guī)則。如果在一個(gè)方法中拋出異常,你有兩個(gè)選擇:要么用catch子句捕獲所有的異常,要么在方法中聲明將要拋出的異常,否則編譯器不會(huì)讓你得逞的。
    方案一:處理異常
        void ex(){
            try{
                throw new Exception();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    方案二:拋出去
        void ex() throws Exception{
            throw new Exception();
        }
    比較一下行數(shù)就知道了,在代碼的世界里推卸責(zé)任也是那么簡(jiǎn)單,一個(gè)throws關(guān)鍵字包含了多少人生哲理啊……現(xiàn)實(shí)生活中我們有很多角色,兒女、父母、學(xué)生、老師、老板、員工……每個(gè)人都占了幾條。可是你能盡到所有責(zé)任嗎?按照古代的孝道,父母尚在人世就不能遠(yuǎn)行。各種責(zé)任是有矛盾的,顧此失彼啊。

    但是這條規(guī)則有個(gè)特例。一個(gè)繼承自Exception名為RuntimeException的子類,也就是運(yùn)行時(shí)異常,不受上述規(guī)則的限制。下面的代碼完全能編譯,只不過(guò)調(diào)用之后在運(yùn)行時(shí)會(huì)拋出異常。
        void ex(){
            throw new RuntimeException();
        }

    14、throw和thrwos關(guān)鍵字。throw用在方法體中拋出異常,后面是一個(gè)具體的異常對(duì)象。throws用在方法參數(shù)列表括號(hào)的后面,用來(lái)聲明此方法會(huì)拋出的異常種類,后面跟著一個(gè)異常類。

    15、非檢查異常。RuntimeException、Error以及它們的子類都是非檢查異常,不要求定義或處理非檢查異常。Java2類庫(kù)中有很多方法拋出檢查異常,因此會(huì)常常編寫(xiě)異常處理程序來(lái)處理不是你編寫(xiě)的方法產(chǎn)生的異常。這種機(jī)制強(qiáng)制開(kāi)發(fā)人員處理錯(cuò)誤,使得Java程序更加健壯,安全。

    16、自定義異常類型。覺(jué)得現(xiàn)有的異常無(wú)法描述你想拋出的異常,ok!Java允許你自定義異常類型,只需要繼承Exception或者它的子類,然后換上有個(gè)性的名字。
        class NotEnoughMoney extends Exception {
            public NotEnoughMoney() {}
            public NotEnoughMoney(String msg) { super(msg); }
        }
    希望大家在生活里不要拋出類似的異常。

    17、重新拋出異常。一個(gè)很無(wú)聊的話題,純粹的語(yǔ)法研究,實(shí)際意義不大。當(dāng)catch子句捕獲到異常之后可以重新拋出,那么它所在的方法必須聲明該異常。
        void ex() throws Exception{
            try {
                throw new Exception();
            }
            catch (Exception mex) {
                throw me;
            }    
        }

    18、異常處理機(jī)制的效率。待補(bǔ)充……

    19、終止與恢復(fù)模型。異常處理理論上有兩種模型:
    一、終止模型。錯(cuò)誤很關(guān)鍵且無(wú)法挽回,再執(zhí)行下去也沒(méi)意義,只能中止。“羅密歐,我們分手吧!”“好吧,朱麗葉!”
    二、恢復(fù)模型。經(jīng)過(guò)錯(cuò)誤修正重新嘗試調(diào)用原來(lái)出問(wèn)題的方法。“羅密歐,我們分手吧!”“朱麗葉,我錯(cuò)了!請(qǐng)?jiān)僭徫乙淮伟桑?#8221;“好的,再原諒你最后一次!”
    顯然我們更喜歡恢復(fù)模型,但在實(shí)際中,這種模式是不易實(shí)現(xiàn)和維護(hù)的。
    例子:用戶輸入了非法的字符,分別按照兩種模式處理
    一、終止模型。輸出出錯(cuò)信息而已,一旦用戶手一抖眼一花你的代碼就崩潰了
        double number;
        String sNumber = "";
        try {
            BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
            sNumber = bf.readLine();
            number = Double.parseDouble(sNumber);    
        } catch (IOException ioe) {
            System.err.println("some IOException");
        } catch (NumberFormatException nfe) {
            System.err.println(sNumber + " is Not a legal number!");
        }
        //System.out.println(number);

    二、恢復(fù)模型。小樣!不輸入正確的數(shù)據(jù)類型就別想離開(kāi)!
        double number = 0;
        String sNumber = "";
        while(true){
            try {
                BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
                sNumber = bf.readLine();
                number = Double.parseDouble(sNumber);
                break;    //如果代碼能執(zhí)行到這一行,就說(shuō)明沒(méi)有拋出異常
            } catch (IOException ioe) {
                System.err.println("some IOException");
            } catch (NumberFormatException nfe) {
                System.err.println(sNumber + " is Not a legal number!");
            }
        }
        System.out.println(number);

    直到用戶輸入正確的信息才會(huì)被該代碼放過(guò)。這是一種簡(jiǎn)單的恢復(fù)模型的實(shí)現(xiàn),挺耐看的,我很喜歡!

    20、try、catch、finally內(nèi)變量的作用域和可見(jiàn)性。
    在try塊內(nèi)定義的變量,它在catch或者finally塊內(nèi)都是無(wú)法訪問(wèn)到的,并且在整個(gè)異常處理語(yǔ)句之外也是不可見(jiàn)的。
    補(bǔ)充一點(diǎn)初始化:第一個(gè)例中最后一句被注釋掉了。number是在運(yùn)行時(shí)由用戶輸入而初始化的,但是在編譯時(shí)刻并沒(méi)有初始化,編譯器會(huì)抱怨的。

    21、輸出異常信息。捕捉到異常之后,通常我們會(huì)輸出相關(guān)的信息,以便更加明確異常。
        catch (Exception mex) {
            System.err.println("caught a exception!");
        }
    用標(biāo)準(zhǔn)錯(cuò)誤流System.err比System.out要好。因?yàn)镾ystem.out也許會(huì)被重定向,System.err則不會(huì)。

    22、更高級(jí)的話題我會(huì)補(bǔ)充上的,但是我的肚子拋出了Hungry異常,我必須catch然后調(diào)用eat()方法補(bǔ)充能量。昨晚的魷魚(yú)蓋澆飯很好吃……


    返回索引頁(yè)


    Feedback

    # re: Java語(yǔ)法總結(jié) - 異常  回復(fù)  更多評(píng)論   

    2007-10-22 10:38 by zhang
    Very good!!1

    # re: Java語(yǔ)法總結(jié) - 異常  回復(fù)  更多評(píng)論   

    2007-10-22 11:27 by Raylong
    @zhang
    謝謝!吃飽了我會(huì)繼續(xù)補(bǔ)充的。

    # re: Java語(yǔ)法總結(jié) - 異常  回復(fù)  更多評(píng)論   

    2007-10-22 11:37 by study
    good!!

    # re: Java語(yǔ)法總結(jié) - 異常  回復(fù)  更多評(píng)論   

    2007-10-22 12:30 by Raylong
    @study
    QQQ!

    # re: Java語(yǔ)法總結(jié) - 異常  回復(fù)  更多評(píng)論   

    2007-10-22 13:09 by it123
    good

    # re: Java語(yǔ)法總結(jié) - 異常  回復(fù)  更多評(píng)論   

    2007-10-22 15:32 by ZelluX

    # re: Java語(yǔ)法總結(jié) - 異常  回復(fù)  更多評(píng)論   

    2007-10-22 17:32 by tomlove
    呼呼,換模板了?  呵呵.繼續(xù)支持

    # re: Java語(yǔ)法總結(jié) - 異常  回復(fù)  更多評(píng)論   

    2007-10-22 21:09 by Raylong
    @tomlove
    DIY的,酷愛(ài)黑色 嘿嘿

    # re: Java語(yǔ)法總結(jié) - 異常  回復(fù)  更多評(píng)論   

    2007-10-22 21:12 by Raylong
    @ZelluX
    日后我換linux系統(tǒng)的時(shí)候還要多多請(qǐng)教你!

    # re: Java語(yǔ)法總結(jié) - 異常  回復(fù)  更多評(píng)論   

    2008-08-06 14:04 by 小瓶子
    期望....

    # re: Java語(yǔ)法總結(jié) - 異常  回復(fù)  更多評(píng)論   

    2008-10-08 23:38 by javie007
    good 很好的比喻

    # re: Java語(yǔ)法總結(jié) - 異常  回復(fù)  更多評(píng)論   

    2010-06-28 09:47 by huanglang
    文筆好,寫(xiě)的生動(dòng)形象
    主站蜘蛛池模板: 成人无码a级毛片免费| 黑人大战亚洲人精品一区| 久久aa毛片免费播放嗯啊| 美女隐私免费视频看| 国产精品亚洲自在线播放页码| 国产亚洲一区二区精品| 夜色阁亚洲一区二区三区 | 在线观看亚洲av每日更新 | 美女免费视频一区二区三区| 亚洲色偷偷偷网站色偷一区| 最新亚洲成av人免费看| 四虎影视永久免费观看网址| 毛片A级毛片免费播放| 亚洲综合免费视频| 久久久久国色av免费看| 色播在线永久免费视频网站| 国产成人无码精品久久久免费| 日韩国产欧美亚洲v片| 亚洲人成网国产最新在线| 亚洲中文字幕在线无码一区二区| 亚洲AV成人精品网站在线播放| 国产亚洲精品精华液| 中文字幕亚洲专区| 亚洲片国产一区一级在线观看| 亚洲第一成人影院| xvideos亚洲永久网址| 国产99视频精品免费视频7| 色吊丝永久在线观看最新免费| 成人爽A毛片免费看| 一个人看www在线高清免费看| 无码国产精品一区二区免费式直播| 1000部夫妻午夜免费| 亚洲免费福利视频| 18观看免费永久视频| 国产电影午夜成年免费视频| 久久久久av无码免费网| 91九色老熟女免费资源站| ww在线观视频免费观看| 最近中文字幕免费mv视频7| 女性自慰aⅴ片高清免费| 日韩免费在线观看|