《瘋狂Java講義》學習筆記(十)異常處理

0、Java的異常體系

一、異常概述


異常機制已經成爲判斷一門編程語言是否成熟的標準,目前主流的編程語言都提供了成熟的異常機制,增長了異常處理機制後的程序有更好的容錯性,更加健壯
Java的異常機制主要依賴於:try、catch、finally、throws和throw
Java7進一步加強了異常處理機制的功能,包括帶資源的try語句、捕獲更多異常的catch
Java將異常分爲兩種,Checked異常和Runtime異常,Checked異常都是能夠在編譯階段被處理的異常,程序強制要求處理;而Runtime異常是運行時產生的異常java


二、異常處理機制


使用try…catch捕獲異常 
try{…}catch(Exception e){…} 
若是執行try塊裏的業務邏輯代碼時出現異常,系統自動生成一個異常對象,該異常對象被提交給Java運行時環境,這個過程被稱爲拋出(throw)異常 
當Java運行時環境收到異常對象時,會尋找能處理該異常對象的catch塊,若是找到合適的則把該異常對象交給該catch塊處理,這個過程被稱爲捕獲異常,不然運行時環境終止,Java程序也將退出編程


三、異常的繼承關係


Java把全部非正常狀況分紅兩種:異常(Exception)和錯誤(Error),它們都是繼承Throwable父類
Error錯誤,通常是指與虛擬機相關的問題,如系統崩潰、虛擬機錯誤、動態連接失敗等,這種錯誤沒法恢復或不可能捕獲,將致使應用程序中斷;一般應用程序沒法處理這些錯誤,所以也沒法捕獲
開發中常遇到的內存溢出是屬於錯誤(Error) 
第一種:OutOfMemoryError: PermGen space內存空間不足,如一次性加載太多信息,或加載項目太多 
第二種:OutOfMemoryError: Java heap spacejava虛擬機建立的對象太多,在進行垃圾回收之間,虛擬機分配的到堆內存空間已經用滿了 
第三種:OutOfMemoryError:unable to create new native thread通常不多出現,可能因爲分配給JVM內存與系統自己比例問題引發
Java7能夠提供更多異常捕獲 
try{…}catch(IndexOutOfBoundsException|NumberFormatException|ArithmeticException ie){…}
訪問異常信息 
getMessage():返回該異常的詳細描述字符串 
printStackTrace():將該異常的跟蹤棧信息輸出到標準錯誤輸出 
printStackTrace(PrintStream s):將該異常的跟蹤信息輸出到指定輸出流 
getStackTrace():返回該異常的跟蹤棧信息編程語言


四、finally塊
 

try{
    ...
}catch(Exception e){
    ...
}finally{
    ...
}


無論try塊中的代碼是否出現異常,也無論哪個catch塊被執行,甚至在try塊或catch塊中執行了return、throw語句,finally塊老是被執行
異常處理語法結構中只有try塊是必須的,catch塊和finally塊都是可選的,但二者至少出現其中之一;能夠有多個catch塊,catch塊必須位於try以後,finally必須位於全部catch塊以後;
若是在異常處理代碼中使用System.exit(1)語句來退出虛擬機,則finally塊將失去執行的機會
在一般狀況下,不要在finally塊中使用如return或throw等致使方法終止的語句,不然會致使try塊、catch塊中的return、throw語句失效spa


五、Java7自動關閉資源的try語句

 

try(BufferedReader br = new BufferedReader(new FileReader("AutoCloseTest.java"));){
    System.out.println(br);
} catch (Exception e) {
    e.printStackTrace();
}


Java7加強了try語句的功能,容許在try關鍵字後緊跟一對圓括號聲明、初始化一個或多個資源,try語句在該語句結束時自動關閉這些資源;並且這些資源實現類必須實現AutoCloseable或Closeable接口,實現這兩個接口就必須實現close()方法
以上的BufferedReader都是實現了Closeable接口的,即便沒有finally塊也會自動關閉資源code


六、Checked異常和Runtime異常體系


全部的RuntimeException類及其子類的實例被稱爲Runtime異常;非RuntimeException類及其子類的異常實例則被稱爲Checked異常
Checked異常處理方式: 
當前方法明確知道如何處理該異常,程序應該使用try…catch塊來捕獲該異常,而後再對應的catch塊中修復該異常 
當方法不知道如何處理這種異常,應該在定義該方法時拋出該異常
Runtime異常則無須顯示聲明拋出,程序也能夠經過try…catch塊來捕獲orm


七、使用throws聲明拋出異常

public class ThrowsTest{
    public static main(String[] args)throws IOException{
        FileInputStream fis = new FileInputStream("a.txt");
    }
}

 

  • 當前方法不知道如何處理這種類型異常時可使用throws聲明拋出異常
  • 使用throws聲明拋出異常時有一個限制:子類方法聲明拋出的異常類型應該是父類方法聲明拋出的異常類型的子類或相同,子類方法聲明拋出異常不容許比父類方法聲明拋出的異常多


八、使用throw拋出異常


當程序出現錯誤時,系統會自動拋出異常,除此以外,Java也容許程序自行拋出異常,使用throw語句來完成對象


九、自定義異常類


用戶自定義異常都應該繼承Exception基類,若是系統自定義Runtime異常,則應該繼承RuntimeException基類blog

public class MyException extends Exception{
    public MyException(){}
        public MyException(String msg){
        super(msg);
    }
    publc MyException(Throwable t){
        super(t);
    }
}


十、catch和throw同時使用


爲了實現經過多方協做處理同一個異常的情形,能夠在catch塊中結合throw語句來完成,將異常傳遞給下一個程序 
Java7能夠直接將捕獲的異常直接傳遞:繼承

try{
    new FileOutputStream("a.txt");
}catch(Exception ex){
    ex.printStackTrack();
    throw ex;
}


十一、異常鏈

public calSal() throws MyException{
    try{
        ...
    }catch(Exception e){
        throw new MyException(e);
    }
}


十二、異常處理規則

  • 成功的異常處理應該實現4個目標: 

        使程序代碼混亂最小化 
        捕獲並保留診斷信息 
        通知合適的人員 
        採用合適的方式結束異常活動接口

  • 避免過分依賴異常: 

        把異常和普通錯誤混淆在一塊兒,再也不編寫任何錯誤處理代碼 
        使用異常處理來替代流程控制

  • 不要使用過於龐大的try塊 

        應該把大塊的try塊分割成多個可能出現異常的程序段落,並把它們放在單獨的try塊中

相關文章
相關標籤/搜索