參考:http://www.cnblogs.com/skywang12345/p/3544168.htmlhtml
Java異常是Java提供的一種識別及響應錯誤的一致性機制(注意:編譯出現的問題叫語法錯誤,不叫異常)。
Java異常機制可使程序中異常處理代碼和正常業務代碼分離,保證程序代碼更加優雅,並提升程序健壯性。在有效使用異常的狀況下,異常能清晰的回答what, where, why這3個問題:異常類型回答了「什麼」被拋出,異常堆棧跟蹤回答了「在哪「拋出,異常信息回答了「爲何「會拋出。Java經過API中Throwable類的衆多子類描述各類不一樣的異常。於是,Java異常都是對象,是Throwable子類的實例。
Java異常機制用到的幾個關鍵字:try、catch、finally、throw、throws。java
查看jdk8的文檔,咱們能夠看到:數據庫
Error類描述了Java運行時系統的內部錯誤和資源耗盡錯誤。大多數錯誤與代碼編寫者執行的操做無關,而表示代碼運行時 JVM(Java 虛擬機)出現的問題。例如,Java虛擬機運行錯誤(Virtual MachineError),當 JVM請求內存不夠時,將出現 OutOfMemoryError。這些異常發生時,Java虛擬機(JVM)通常會選擇線程終止。數組
Exception類是程序自己能夠處理的異常。通常分爲兩個分支:一個分支派生於RuntimeException;另外一個分支包含其餘異常,即非運行時異常。
RuntimeException 類表示由程序錯誤致使的異常,好比若試圖使用空值對象引用、除數爲零或數組越界,則分別引起運行時異常(NullPointerException、ArithmeticException)和 ArrayIndexOutOfBoundException。若是出現了運行時異常,那麼必定是你的問題。這些異常是未檢查異常,程序中能夠選擇捕獲處理,也能夠不處理。這些異常通常是由程序邏輯錯誤引發的,程序應該從邏輯角度儘量避免這類異常的發生。
運行時異常的特色是Java編譯器不會檢查它,也就是說,當程序中可能出現這類異常,即便沒有用try-catch語句捕獲它,也沒有經過throws進行聲明拋出,也會編譯經過。網絡
程序自己沒有問題,但因爲像IO錯誤這類問題致使的異常屬於其餘異常,即非運行時異常,好比如IOException、SQLException等以及用戶自定義的Exception異常。從程序語法角度講必須進行處理,若是不處理,程序就不能編譯經過。
線程
一般,Java的異常(包括Exception和Error)分爲已檢查異常(checked exceptions)和未檢查的異常(unchecked exceptions)。
未檢查的異常:派生於Error類和RuntimeException 類的全部異常。
已檢查的異常:全部其餘的異常。編譯器將覈查是否爲全部的已檢查異常提供了異常處理器。也就是說:這種異常的特色是Java編譯器會檢查它,當程序中可能出現這類異常,要麼用try-catch語句捕獲它,要麼經過throws進行聲明拋出,不然編譯不會經過。3d
注意:異常和錯誤的區別:異常能被程序自己能夠處理,錯誤是沒法處理。指針
一個方法必須聲明全部可能拋出的已檢查異常,而未檢查異常要麼不可控制(Error類),要麼就應該避免(RuntimeException 類)。若是方法沒有聲明全部可能發生的已檢查異常,編譯器就會給出一個錯誤信息。固然,除了聲明異常外,還能夠捕獲異常,這樣會使異常不被拋到方法以外,也不須要throws規範。
在 Java 應用程序中,異常處理機制爲:拋出異常,捕捉異常。code
拋出異常:當一個方法出現錯誤引起異常時,方法建立異常對象並交付運行時系統,異常對象中包含了異常類型和異常出現時的程序狀態等異常信息,運行時系統負責尋找處置異常的代碼並執行。從方法中拋出的任何異常都必須使用throws子句。
捕獲異常:捕捉異常經過try-catch語句或者try-catch-finally語句實現。orm
對於運行時異常、錯誤或已檢查異常,Java技術所要求的異常處理方式有所不一樣。
因爲運行時異常的不可查性,爲了更合理、更容易地實現應用程序,Java規定,運行時異常將由Java運行時系統自動拋出,容許應用程序忽略運行時異常。
對於方法運行中可能出現的Error,當運行方法不欲捕捉時,Java容許該方法不作任何拋出聲明。由於,大多數Error異常屬於永遠不能被容許發生的情況,也屬於合理的應用程序不應捕捉的異常。
對於全部的已檢查異常,Java規定:一個方法必須捕捉,或者聲明拋出到方法以外。也就是說,當一個方法選擇不捕捉已檢查異常時,它必須聲明拋出異常。可以捕捉異常的方法,須要提供相符類型的異常處理器。所捕捉的異常,多是因爲自身語句所引起並拋出的異常,也多是由某個調用的方法或者Java運行時系統等拋出的異常。也就是說,一個方法所能捕捉的異常,必定是Java代碼在某處所拋出的異常。簡單地說,異常老是先被拋出,後被捕捉的。
整體來講,Java規定:對於已檢查異常必須捕捉、或者聲明拋出,容許忽略不可查的RuntimeException和Error。
try 塊:用於捕獲異常。其後可接零個或多個catch塊,若是沒有catch塊,則必須跟一個finally塊。
catch 塊:用於處理try捕獲到的異常。
finally 塊:不管是否捕獲或處理異常,finally塊裏的語句都會被執行。當在try塊或catch塊中遇到return語句時,finally語句塊將在方法返回以前被執行。在如下4種特殊狀況下,finally塊不會被執行:
1)在finally語句塊中發生了異常。
2)在前面的代碼中用了System.exit()退出程序。
3)程序所在的線程死亡。
4)關閉CPU。
public static void main(String[] args) { try { int i = 10/0; System.out.println("i="+i); } catch (ArithmeticException e) { System.out.println("Caught Exception"); System.out.println("e.getMessage(): " + e.getMessage()); System.out.println("e.toString(): " + e.toString()); System.out.println("e.printStackTrace():"); e.printStackTrace(); } finally { System.out.println("run finally"); } }
輸出:
結果說明:在try語句塊中有除數爲0的操做,該操做會拋出java.lang.ArithmeticException異常。經過catch,對該異常進行捕獲。 觀察結果咱們發現,並無執行System.out.println("i="+i)。這說明try語句塊發生異常以後,try語句塊中的剩餘內容就不會再被執行了,而且最終執行了finally語句塊。