異常機制已經成爲判斷一門編程語言是否成熟的標準,目前主流的編程語言都提供了成熟的異常機制,增長了異常處理機制後的程序有更好的容錯性,更加健壯
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():返回該異常的跟蹤棧信息編程語言
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
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
全部的RuntimeException類及其子類的實例被稱爲Runtime異常;非RuntimeException類及其子類的異常實例則被稱爲Checked異常
Checked異常處理方式:
當前方法明確知道如何處理該異常,程序應該使用try…catch塊來捕獲該異常,而後再對應的catch塊中修復該異常
當方法不知道如何處理這種異常,應該在定義該方法時拋出該異常
Runtime異常則無須顯示聲明拋出,程序也能夠經過try…catch塊來捕獲orm
public class ThrowsTest{ public static main(String[] args)throws IOException{ FileInputStream fis = new FileInputStream("a.txt"); } }
當程序出現錯誤時,系統會自動拋出異常,除此以外,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語句來完成,將異常傳遞給下一個程序
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); } }
使程序代碼混亂最小化
捕獲並保留診斷信息
通知合適的人員
採用合適的方式結束異常活動接口
把異常和普通錯誤混淆在一塊兒,再也不編寫任何錯誤處理代碼
使用異常處理來替代流程控制
應該把大塊的try塊分割成多個可能出現異常的程序段落,並把它們放在單獨的try塊中