JavaSE基礎--(四)異常處理

### java異常處理語法結構 ###
    try// 業務實現代碼
        }
        catch
        {
            // 異常處理塊1
        }
        catch
        {
            // 異常處理塊2
        }
        finally
        {
            // 資源回收快
### 異常概述 ###
    異常機制可以使程序中的異常處理代碼和正常業務代碼分離。
    先處理小異常,再處理大異常。
    異常能處理就早處理,拋出不去還不能處理的就想法消化掉或者轉換爲RuntimeException處理。
    可以把錯誤集中起來,一次處理所有的錯誤。
    五個關鍵字try,catch,finally,throw,throws
    其中try...catch用來捕捉異常。        
    拋出大量異常是有問題的,應該從程序開發角度儘可能的控制異常發生的可能。
    不要使用過於龐大的try塊,造成後面緊跟大量的catch,導致分析異常原因的難度大大增加。
    儘量避免在實際應用中捕捉Throwable。
    不要忽略捕捉到的異常,catch爲空或僅僅打印出錯信息都是不妥的,要處理異常或重新拋出異常。

### 作用以及限制 ###
    作用:
        ①what       
                如果異常機制使用恰當,被拋出異常的類型可以表明發生了什麼程序錯誤。       
        ②where      
               發生異常之後,而Stack Trace可以清楚的告訴我們什麼地方發生了錯誤。       
        ③why    
                爲什麼發生錯誤則可以通過看異常信息和Stack Trace來分析。

        如果你的異常不能解決上面的3W問題,那麼可以證明你對異常使用一定不正確。    
    限制:
        1 把異常和普通錯誤混在一起。
        2 使用異常處理代替流程控制。
    其實,對於普通的錯誤,應該編寫處理這種錯誤的代碼,增加程序的健壯性,只用對外部的、不能確定和預知的運行時錯誤才使用異常。不要使用一場來代替正常的業務邏輯判斷。
### try塊裏聲明的變量只能在try塊裏有效,在catch塊裏不可以使用

### 分類 ###   
    1 Error與Exception
        Error:稱爲錯誤,由Java虛擬機生成並拋出,包括動態鏈接失敗、虛擬機錯誤等,程序對其不做處理,也可以說成不可以處理的異常。
        Exception:所有異常類的父類,其子類對應了各種各種具體可能出現的異常事件,一般需要用戶聲明或捕獲,也叫可處理的異常。  
    2 runtimeException與非運行時異常(其他異常)
        runtimeException:一類特殊的異常,如被0除、數組下界超範圍,其產生比較頻繁,處理麻煩,如果聲明或捕獲將會對程序可讀性和運行效率影響很大。因此係統自動檢測並將它們交給缺省的異常處理程序,這樣的異常可以處理也可以不處理。

        非運行時異常:是RuntimeException以外的異常,類型上都屬於Exception類及其子類,這類異常是必須要處理的異常,否則程序就不能編譯通過。
### 可同時捕獲多個異常 ###
    捕獲多異常,異常類型用 | 分開;
    捕獲多異常時,異常變量有隱形的final修飾,因此程序不能對異常變量重新賦值。
### 訪問異常信息的方法  ###
    printStackTrace():將跟蹤棧信息輸出到標準錯誤輸出。
    雖然printStackTrace可以很方便的追蹤異常的發生情況,可以用來調試程序,但在最後發佈的程序中,應該避免使用它,而應該對捕獲的一場進行適當的處理。
    getStackTrace():返回該異常的跟蹤棧信息。
### finally ###
    回收try塊中打開的一些物理資源(數據庫連接,網絡連接,和磁盤連接等)。
    java的垃圾回收機制不會回收任何物理資源,只能回收堆內存中對象所佔用的內存。
    除非在try塊或catch塊裏調用了退出JVM的System.exit(),否則異常處理的finally塊總會執行。
    通常情況下不要再finally塊中使用return或throw語句,否則會導致try、catch裏的throw、return語句失效。
### 自動關閉資源的try語句 ###

### throws ###
    如果某段代碼調用了一個帶有throws聲明的方法,拋出checked異常,則表明該方法希望他的調用者來處理該異常。
    否則將異常交給JVM處理,打印異常的跟蹤棧信息,並終止程序運行。
    子類拋出的異常不允許比父類多。
### throw 及自定義異常類###
    自行拋出異常時,拋出RuntimeException更好,更靈活
    throw new Exception     
    程序:
```
public class ThrowTest
            {
                public static void main(String[] args) 
                {
                    try
                    {
                        // 調用聲明拋出Checked異常的方法,要麼顯式捕獲該異常
                        // 要麼在main方法中再次聲明拋出
                        throwChecked(-3);
                    }
                    catch (Exception e)
                    {
                        System.out.println(e.getMessage());
                    }
                    // 調用聲明拋出Runtime異常的方法既可以顯式捕獲該異常,
                    // 也可不理會該異常
                    throwRuntime(3);
                }
                public static void throwChecked(int a)throws Exception
                {
                    if (a > 0)
                    {
                        //自行拋出Exception異常
                        //該代碼必須處於try塊裏,或處於帶throws聲明的方法中
                        throw new Exception("a的值大於0,不符合要求");
                    }
                }
                public static void throwRuntime(int a)
                {
                    if (a > 0)
                    {
                        //自行拋出RuntimeException異常,既可以顯式捕獲該異常
                        //也可完全不理會該異常,把該異常交給該方法調用者處理
                        throw new RuntimeException("a的值大於0,不符合要求");
                    }
                }
            }
        很少拋出自定義異常類
    ### catch和throw同時使用 ###

        public class AuctionTest
        {
            private double initPrice = 30.0;
            // 因爲該方法中顯式拋出了AuctionException異常,
            // 所以此處需要聲明拋出AuctionException異常
            public void bid(String bidPrice)
                throws AuctionException
            {
                double d = 0.0;
                try
                {
                    d = Double.parseDouble(bidPrice);
                }
                catch (Exception e)
                {
                    // 此處完成本方法中可以對異常執行的修復處理,
                    // 此處僅僅是在控制檯打印異常跟蹤棧信息。
                    e.printStackTrace();
                    //再次拋出自定義異常
                    throw new AuctionException("競拍價必須是數值,"
                        + "不能包含其他字符!");
                }
                if (initPrice > d)
                {
                    throw new AuctionException("競拍價比起拍價低,"
                        + "不允許競拍!");
                }
                initPrice = d;
            }
            public static void main(String[] args) 
            {
                AuctionTest at = new AuctionTest();
                try
                {
                    at.bid("df");
                }
                catch (AuctionException ae)
                {
                    // 再次捕捉到bid方法中的異常。並對該異常進行處理
                    System.err.println(ae.getMessage());
                }
            }
        }

“`
catch和throw結合使用的情況在大型企業級應用中使用的非常頻繁,使用方法:
1 通過日誌記錄異常發生時的情況
2 應用需要根據應用使用者傳達某種提示

發佈了18 篇原創文章 · 獲贊 41 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章