leochiang

          BlogJava 聯系 聚合 管理
            21 Posts :: 0 Stories :: 1 Comments :: 0 Trackbacks

                http://lavasoft.blog.51cto.com/62575/18920/ 


                Java對異常進行了分類,不同類型的異常分別用不同的Java類表示,所有異常的根類為java.lang.ThrowableThrowable下面又派生了兩個子類:ErrorExceptionError 表示應用程序本身無法克服和恢復的一種嚴重問題,程序只有死的份了,例如,說內存溢出和線程死鎖等系統問題。Exception表示程序還能夠克服和恢復的問題,其中又分為系統異常和普通異常,系統異常是軟件本身缺陷所導致的問題,也就是軟件開發人員考慮不周所導致的問題,軟件使用者無法克服和恢復這種問題,但在這種問題下還可以讓軟件系統繼續運行或者讓軟件死掉,例如,數組腳本越界(ArrayIndexOutOfBoundsException),空指針異常(NullPointerException)、類轉換異常(ClassCastException);普通異常是運行環境的變化或異常所導致的問題,是用戶能夠克服的問題,例如,網絡斷線,硬盤空間不夠,發生這樣的異常后,程序不應該死掉。

                java為系統異常和普通異常提供了不同的解決方案,編譯器強制普通異常必須try..catch處理或用throws聲明繼續拋給上層調用方法處理,所以普通異常也稱為checked異常,而系統異常可以處理也可以不處理,所以,編譯器不強制用try..catch處理或用throws聲明,所以系統異常也稱為unchecked異常。

                Java異常處理通過5個關鍵字try、catch、throw、throws、finally進行管理。基本過程是用try語句塊包住要監視的語句,如果在try語句塊內出現異常,則異常會被拋出,你的代碼在catch語句塊中可以捕獲到這個異常并做處理;還有以部分系統生成的異常在Java運行時自動拋出。你也可以通過throws關鍵字在方法上聲明該方法要拋出異常,然后在方法內部通過throw拋出異常對象。finally語句塊會在方法執行return之前執行,一般結構如下:

           try{
            程序代碼
           }catch(異常類型1 異常的變量名1){
            程序代碼
           }catch(異常類型2 異常的變量名2){
            程序代碼
           }finally{
            程序代碼
           }
                  catch語句可以有多個,用來匹配多個異常,匹配上多個中一個后,執行catch語句塊時候僅僅執行匹配上的異常。catch的類型是Java語言中定義的或者程序員自己定義的,表示代碼拋出異常的類型,異常的變量名表示拋出異常的對象的引用,如果catch捕獲并匹配上了該異常,那么就可以直接用這個異常變量名,此時該異常變量名指向所匹配的異常,并且在catch代碼塊中可以直接引用。這一點非常非常的特殊和重要!
                  Java異常處理的目的是提高程序的健壯性,你可以在catch和finally代碼塊中給程序一個修正機會,使得程序不因異常而終止或者流程發生以外的改變。同時,通過獲取Java異常信息,也為程序的開發維護提供了方便,一般通過異常信息就很快就能找到出現異常的問題(代碼)所在。
                  Java異常處理是Java語言的一大特色,也是個難點,掌握異常處理可以讓寫的代碼更健壯和易于維護。

          下面是這幾個類的層次圖:
          java.lang.Object
            java.lang.Throwable
                java.lang.Exception
                 java.lang.RuntimeException
             java.lang.Error
                 java.lang.ThreadDeath
           
          下面四個類的介紹來自java api 文檔。
           
          1、Throwable
                  Throwable 類是 Java 語言中所有錯誤或異常的超類。只有當對象是此類(或其子類之一)的實例時,才能通過 Java 虛擬機或者 Java throw 語句拋出。類似地,只有此類或其子類之一才可以是 catch 子句中的參數類型。
          兩個子類的實例,Error 和 Exception,通常用于指示發生了異常情況。通常,這些實例是在異常情況的上下文中新近創建的,因此包含了相關的信息(比如堆棧跟蹤數據)。
           
          2、Exception
                  Exception 類及其子類是 Throwable 的一種形式,它指出了合理的應用程序想要捕獲的條件,表示程序本身可以處理的異常。
           
          3、Error
                  Error 是 Throwable 的子類,表示僅靠程序本身無法恢復的嚴重錯誤,用于指示合理的應用程序不應該試圖捕獲的嚴重問題。
          在執行該方法期間,無需在方法中通過throws聲明可能拋出但沒有捕獲的 Error 的任何子類,因為Java編譯器不去檢查它,也就是說,當程序中可能出現這類異常時,即使沒有用try...catch語句捕獲它,也沒有用throws字句聲明拋出它,還是會編譯通過。
           
          4、RuntimeException
                  RuntimeException 是那些可能在 Java 虛擬機正常運行期間拋出的異常的超類。Java編譯器不去檢查它,也就是說,當程序中可能出現這類異常時,即使沒有用try...catch語句捕獲它,也沒有用throws字句聲明拋出它,還是會編譯通過,這種異常可以通過改進代碼實現來避免。
           
          5、ThreadDeath
                  調用 Thread 類中帶有零參數的 stop 方法時,受害線程將拋出一個 ThreadDeath 實例。
                  僅當應用程序在被異步終止后必須清除時才應該捕獲這個類的實例。如果 ThreadDeath 被一個方法捕獲,那么將它重新拋出非常重要,因為這樣才能讓該線程真正終止。
          如果沒有捕獲 ThreadDeath,則頂級錯誤處理程序不會輸出消息。
                  雖然 ThreadDeath 類是“正常出現”的,但它只能是 Error 的子類而不是 Exception 的子類,因為許多應用程序捕獲所有出現的 Exception,然后又將其放棄。

           對于可能出現異常的代碼,有兩種處理辦法:
                  第一、在方法中用try...catch語句捕獲并處理異常,catach語句可以有多個,用來匹配多個異常。例如:
          public void p(int x){
           try{
            ...
           }catch(Exception e){
            ...
           }finally{
            ...
           }
          }
           
          第二、對于處理不了的異常或者要轉型的異常,在方法的聲明處通過throws語句拋出異常。例如:
          public void test1() throws MyException{
           ...
           if(....){
            throw new MyException();
           }
                  如果每個方法都是簡單的拋出異常,那么在方法調用方法的多層嵌套調用中,Java虛擬機會從出現異常的方法代碼塊中往回找,直到找到處理該異常的代碼塊為止。然后將異常交給相應的catch語句處理。如果Java虛擬機追溯到方法調用棧最底部main()方法時,如果仍然沒有找到處理異常的代碼塊,將按照下面的步驟處理:
                  第一、調用異常的對象的printStackTrace()方法,打印方法調用棧的異常信息。
                  第二、如果出現異常的線程為主線程,則整個程序運行終止;如果非主線程,則終止該線程,其他線程繼續運行。
                  通過分析思考可以看出,越早處理異常消耗的資源和時間越小,產生影響的范圍也越小。因此,不要把自己能處理的異常也拋給調用者。
                  還有一點,不可忽視:finally語句在任何情況下都必須執行的代碼,這樣可以保證一些在任何情況下都必須執行代碼的可靠性。比如,在數據庫查詢異常的時候,應該釋放JDBC連接等等。finally語句先于return語句執行,而不論其先后位置,也不管是否try塊出現異常。finally語句唯一不被執行的情況是方法執行了System.exit()方法。System.exit()的作用是終止當前正在運行的 Java 虛擬機。finally語句塊中不能通過給變量賦新值來改變return的返回值,也建議不要在finally塊中使用return語句,沒有意義還容易導致錯誤。
           
                  最后還應該注意一下異常處理的語法規則:
                  第一、try語句不能單獨存在,可以和catch、finally組成 try...catch...finally、try...catch、try...finally三種結構,catch語句可以有一個或多個,finally語句最多一個,try、catch、finally這三個關鍵字均不能單獨使用。
                  第二、try、catch、finally三個代碼塊中變量的作用域分別獨立而不能相互訪問。如果要在三個塊中都可以訪問,則需要將變量定義到這些塊的外面。
                  第三、多個catch塊時候,Java虛擬機會匹配其中一個異常類或其子類,就執行這個catch塊,而不會再執行別的catch塊。
                  第四、throw語句后不允許有緊跟其他語句,因為這些沒有機會執行。
                  第五、如果一個方法調用了另外一個聲明拋出異常的方法,那么這個方法要么處理異常,要么聲明拋出。
           
                  那怎么判斷一個方法可能會出現異常呢?一般來說,方法聲明的時候用了throws語句,方法中有throw語句,方法調用的方法聲明有throws關鍵字。
           
                  throw和throws關鍵字的區別
                  throw用來拋出一個異常,在方法體內。語法格式為:throw 異常對象。
                  throws用來聲明方法可能會拋出什么異常,在方法名后,語法格式為:throws 異常類型1,異常類型2...異常類型n。

          posted on 2012-08-12 07:44 leoChiang 閱讀(1070) 評論(0)  編輯  收藏 所屬分類: 技術文檔
          主站蜘蛛池模板: 象州县| 闽侯县| 曲阳县| 和平县| 福贡县| 陇西县| 京山县| 华池县| 封丘县| 贵阳市| 静海县| 上高县| 齐河县| 卢氏县| 大埔区| 大化| 巍山| 鄂伦春自治旗| 巴东县| 天峻县| 泸西县| 花莲县| 贵州省| 修水县| 富川| 金沙县| 渑池县| 花莲市| 景德镇市| 沁水县| 茂名市| 新绛县| 建始县| 昌宁县| 梨树县| 平邑县| 盐亭县| 定西市| 伽师县| 青河县| 佛学|