java異常

java異常

參考: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

  • try:用於監聽。將要被監聽的代碼(可能拋出異常的代碼)放在try語句塊以內,當try語句塊內發生異常時,異常就被拋出。
  • catch:用於捕獲異常。catch用來捕獲try語句塊中發生的異常。
  • finally:finally語句塊老是會被執行。它主要用於回收在try塊裏打開的物理資源(如數據庫鏈接、網絡鏈接和磁盤文件)。finally塊執行完成以後,纔會回來執行try或者catch塊中的return或者throw語句,若是finally中使用了return或者throw等終止方法的語句,就不會跳回執行,直接中止。
  • throw:用於拋出異常。
  • throws:用在方法簽名中,用於聲明該方法可能拋出的異常。

Java異常類層次結構圖

查看jdk8的文檔,咱們能夠看到:數據庫

  • Error的直接子類:AnnotationFormatError, FactoryConfigurationError, IOError, ServiceConfigurationError, ThreadDeath, VirtualMachineError ...
  • Exception 的直接子類: DataFormatException, IllegalClassFormatException, InterruptedException, IOException, ReflectiveOperationException, RuntimeException, SQLException, TimeoutException...
  • Exception的子類RuntimeException的子類: ArithmeticException(算數異常), BufferOverflowException(緩衝區溢出異常), ClassCastException(類型轉換異常), IndexOutOfBoundsException(數組越界異常), NullPointerException(空指針異常)...

Error類

  Error類描述了Java運行時系統的內部錯誤和資源耗盡錯誤。大多數錯誤與代碼編寫者執行的操做無關,而表示代碼運行時 JVM(Java 虛擬機)出現的問題。例如,Java虛擬機運行錯誤(Virtual MachineError),當 JVM請求內存不夠時,將出現 OutOfMemoryError。這些異常發生時,Java虛擬機(JVM)通常會選擇線程終止。數組

Exception類

運行時異常

  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。

例子

例子1

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語句塊。

相關文章
相關標籤/搜索