1. 程式人生 > >4.java異常處理

4.java異常處理

引.

  try…catch…finally恐怕是大家再熟悉不過的語句了,而且感覺用起來也是很簡單,邏輯上似乎也是很容易理解。不過,我親自體驗的“教訓”告訴我,這個東西可不是想象中的那麼簡單、聽話。不信?那你看看下面的程式碼,“猜猜”它執行後的結果會是什麼?不要往後看答案、也不許執行程式碼看真正答案哦。如果你的答案是正確,那麼這篇文章你就不用浪費時間看啦。

[java] view plain copy  print?在CODE上檢視程式碼片派生到我的程式碼片
  1. package Test;  
  2. publicclass TestException {  
  3.     public TestException() {  
  4.     }  
  5.     boolean testEx() throws Exception {  
  6.         boolean ret = true;  
  7.         try {  
  8.             ret = testEx1();  
  9.         } catch (Exception e) {  
  10.             System.out.println("testEx, catch exception");  
  11.             ret = false;  
  12.             throw e;  
  13.         } finally
     {  
  14.             System.out.println("testEx, finally; return value=" + ret);  
  15.             return ret;  
  16.         }  
  17.     }  
  18.     boolean testEx1() throws Exception {  
  19.         boolean ret = true;  
  20.         try {  
  21.             ret = testEx2();  
  22.             if (!ret) {  
  23.                 return
    false;  
  24.             }  
  25.             System.out.println("testEx1, at the end of try");  
  26.             return ret;  
  27.         } catch (Exception e) {  
  28.             System.out.println("testEx1, catch exception");  
  29.             ret = false;  
  30.             throw e;  
  31.         } finally {  
  32.             System.out.println("testEx1, finally; return value=" + ret);  
  33.             return ret;  
  34.         }  
  35.     }  
  36.     boolean testEx2() throws Exception {  
  37.         boolean ret = true;  
  38.         try {  
  39.             int b = 12;  
  40.             int c;  
  41.             for (int i = 2; i >= -2; i--) {  
  42.                 c = b / i;  
  43.                 System.out.println("i=" + i);  
  44.             }  
  45.             returntrue;  
  46.         } catch (Exception e) {  
  47.             System.out.println("testEx2, catch exception");  
  48.             ret = false;  
  49.             throw e;  
  50.         } finally {  
  51.             System.out.println("testEx2, finally; return value=" + ret);  
  52.             return ret;  
  53.         }  
  54.     }  
  55.     publicstaticvoid main(String[] args) {  
  56.         TestException testException1 = new TestException();  
  57.         try {  
  58.             testException1.testEx();  
  59.         } catch (Exception e) {  
  60.             e.printStackTrace();  
  61.         }  
  62.     }  
  63. }  

你的答案是什麼?是下面的答案嗎?

i=2
i=1
testEx2, catch exception
testEx2, finally; return value=false
testEx1, catch exception
testEx1, finally; return value=false
testEx, catch exception
testEx, finally; return value=false

如果你的答案真的如上面所說,那麼你錯啦。^_^,那就建議你仔細看一看這篇文章或者拿上面的程式碼按各種不同的情況修改、執行、測試,你會發現有很多事情不是原來想象中的那麼簡單的。現在公佈正確答案:

i=2
i=1
testEx2, catch exception
testEx2, finally; return value=false
testEx1, finally; return value=false
testEx, finally; return value=false

注意說明:

finally語句塊不應該出現 應該出現return。上面的return ret最好是其他語句來處理相關邏輯。

 2.Java異常

異常指不期而至的各種狀況,如:檔案找不到、網路連線失敗、非法引數等。異常是一個事件,它發生在程式執行期間,干擾了正常的指令流程。Java通 過API中Throwable類的眾多子類描述各種不同的異常。因而,Java異常都是物件,是Throwable子類的例項,描述了出現在一段編碼中的 錯誤條件。當條件生成時,錯誤將引發異常。

      Java異常類層次結構圖:


        

                                                                    圖1 Java異常類層次結構圖

        在 Java 中,所有的異常都有一個共同的祖先 Throwable(可丟擲)。Throwable 指定程式碼中可用異常傳播機制通過 Java 應用程式傳輸的任何問題的共性。
       Throwable: 有兩個重要的子類:Exception(異常)和 Error(錯誤),二者都是 Java 異常處理的重要子類,各自都包含大量子類。

       Error(錯誤):是程式無法處理的錯誤,表示執行應用程式中較嚴重問題。大多數錯誤與程式碼編寫者執行的操作無關,而表示程式碼執行時 JVM(Java 虛擬機器)出現的問題。例如,Java虛擬機器執行錯誤(Virtual MachineError),當 JVM 不再有繼續執行操作所需的記憶體資源時,將出現 OutOfMemoryError。這些異常發生時,Java虛擬機器(JVM)一般會選擇執行緒終止。

。這些錯誤表示故障發生於虛擬機器自身、或者發生在虛擬機器試圖執行應用時,如Java虛擬機器執行錯誤(Virtual MachineError)、類定義錯誤(NoClassDefFoundError)等。這些錯誤是不可查的,因為它們在應用程式的控制和處理能力之 外,而且絕大多數是程式執行時不允許出現的狀況。對於設計合理的應用程式來說,即使確實發生了錯誤,本質上也不應該試圖去處理它所引起的異常狀況。在 Java中,錯誤通過Error的子類描述。

       Exception(異常):是程式本身可以處理的異常。

       Exception 類有一個重要的子類 RuntimeException。RuntimeException 類及其子類表示“JVM 常用操作”引發的錯誤。例如,若試圖使用空值物件引用、除數為零或陣列越界,則分別引發執行時異常(NullPointerException、ArithmeticException)和 ArrayIndexOutOfBoundException。

   注意:異常和錯誤的區別:異常能被程式本身可以處理,錯誤是無法處理。

通常,Java的異常(包括Exception和Error)分為可查的異常(checked exceptions)和不可查的異常(unchecked exceptions)
可查異常(編譯器要求必須處置的異常):正確的程式在執行中,很容易出現的、情理可容的異常狀況可查異常雖然是異常狀況,但在一定程度上它的發生是可以預計的,而且一旦發生這種異常狀況,就必須採取某種方式進行處理。

      除了RuntimeException及其子類以外,其他的Exception類及其子類都屬於可查異常。這種異常的特點是Java編譯器會檢查它,也就是說,當程式中可能出現這類異常,要麼用try-catch語句捕獲它,要麼用throws子句宣告丟擲它,否則編譯不會通過。

不可查異常(編譯器不要求強制處置的異常):包括執行時異常(RuntimeException與其子類)和錯誤(Error)。

     Exception 這種異常分兩大類執行時異常和非執行時異常(編譯異常)。程式中應當儘可能去處理這些異常。

       執行時異常:都是RuntimeException類及其子類異常,如NullPointerException(空指標異常)、IndexOutOfBoundsException(下標越界異常)等,這些異常是不檢查異常,程式中可以選擇捕獲處理,也可以不處理。這些異常一般是由程式邏輯錯誤引起的,程式應該從邏輯角度儘可能避免這類異常的發生。

      執行時異常的特點是Java編譯器不會檢查它,也就是說,當程式中可能出現這類異常,即使沒有用try-catch語句捕獲它,也沒有用throws子句宣告丟擲它,也會編譯通過。
       非執行時異常 (編譯異常):是RuntimeException以外的異常,型別上都屬於Exception類及其子類。從程式語法角度講是必須進行處理的異常,如果不處理,程式就不能編譯通過。如IOException、SQLException等以及使用者自定義的Exception異常,一般情況下不自定義檢查異常

 4.處理異常機制

在 Java 應用程式中,異常處理機制為:丟擲異常,捕捉異常。

        丟擲異常當一個方法出現錯誤引發異常時,方法建立異常物件並交付執行時系統,異常物件中包含了異常型別和異常出現時的程式狀態等異常資訊。執行時系統負責尋找處置異常的程式碼並執行。

        捕獲異常:在方法丟擲異常之後,執行時系統將轉為尋找合適的異常處理器(exception handler)。潛在的異常處理器是異常發生時依次存留在呼叫棧中的方法的集合。當異常處理器所能處理的異常型別與方法丟擲的異常型別相符時,即為合適 的異常處理器。執行時系統從發生異常的方法開始,依次回查呼叫棧中的方法,直至找到含有合適異常處理器的方法並執行。當執行時系統遍歷呼叫棧而未找到合適 的異常處理器,則執行時系統終止。同時,意味著Java程式的終止。

        對於執行時異常、錯誤或可查異常,Java技術所要求的異常處理方式有所不同。

        由於執行時異常的不可查性,為了更合理、更容易地實現應用程式,Java規定,執行時異常將由Java執行時系統自動丟擲,允許應用程式忽略執行時異常。

       對於方法執行中可能出現的Error,當執行方法不欲捕捉時,Java允許該方法不做任何丟擲宣告。因為,大多數Error異常屬於永遠不能被允許發生的狀況,也屬於合理的應用程式不該捕捉的異常。

       對於所有的可查異常,Java規定:一個方法必須捕捉,或者宣告丟擲方法之外。也就是說,當一個方法選擇不捕捉可查異常時,它必須宣告將丟擲異常。

        能夠捕捉異常的方法,需要提供相符型別的異常處理器。所捕捉的異常,可能是由於自身語句所引發並丟擲的異常,也可能是由某個呼叫的方法或者Java執行時 系統等丟擲的異常。也就是說,一個方法所能捕捉的異常,一定是Java程式碼在某處所丟擲的異常簡單地說,異常總是先被丟擲,後被捕捉的。

         任何Java程式碼都可以丟擲異常,如:自己編寫的程式碼、來自Java開發環境包中程式碼,或者Java執行時系統。無論是誰,都可以通過Java的throw語句丟擲異常。

        從方法中丟擲的任何異常都必須使用throws子句。

        捕捉異常通過try-catch語句或者try-catch-finally語句實現。

         總體來說,Java規定:對於可查異常必須捕捉、或者宣告丟擲。允許忽略不可查的RuntimeException和Error。

4.1 捕獲異常:try、catch 和 finally

1.try-catch語句

在Java中,異常通過try-catch語句捕獲。其一般語法形式為:

[java] view plain copy  print?在CODE上檢視程式碼片派生到我的程式碼片
  1. try {  
  2.     // 可能會發生異常的程式程式碼
  3. catch (Type1 id1){  
  4.     // 捕獲並處置try丟擲的異常型別Type1
  5. }  
  6. catch (Type2 id2){  
  7.      //捕獲並處置try丟擲的異常型別Type2
  8. }  

 關鍵詞try後的一對大括號將一塊可能發生異常的程式碼包起來,稱為監控區域。Java方法在執行過程中出現異常,則建立異常物件。將異常丟擲監控區域之 外,由Java執行時系統試圖尋找匹配的catch子句以捕獲異常。若有匹配的catch子句,則執行其異常處理程式碼,try-catch語句結束。

       匹配的原則是:如果丟擲的異常物件屬於catch子句的異常類,或者屬於該異常類的子類,則認為生成的異常物件與catch塊捕獲的異常型別相匹配。

例1  捕捉throw語句丟擲的“除數為0”異常。

[java] view plain copy  print?在CODE上檢視程式碼片派生到我的程式碼片
  1. publicclass TestException {  
  2. 相關推薦

    4.java異常處理

    引.   try…catch…finally恐怕是大家再熟悉不過的語句了,而且感覺用起來也是很簡單,邏輯上似乎也是很容易理解。不過,我親自體驗的“教訓”告訴我,這個東西可不是想象中的那麼簡單、聽話。不信?那你看看下面的程式碼,“猜猜”它執行後的結果會是什麼?不要

    Java 異常處理和 Log4j 配置文件

    images orm 信息 not bound img source jar 下標 一、 程序錯誤 警告:黃線:Warning 錯誤:資源類:系統級(線程)/ 環境級(繪圖) 異常:編譯級:Exception 運行級:Exception -> RuntimeExc

    15. Java異常處理

    ace hover 避免 構造函數 裏的 width 原因 sans 克隆對象 html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,addre

    java異常處理

    並不是 9.png 代碼塊 可能 函數 處理異常 finall int 將不 一 異常: 是指程序運行的過程中,發生某些意外的事情,比如10除以0, 文件不存在等。 例如: pub

    項目中java異常處理

    tails 驗證 包含 erro csdn 拋出異常 項目 cep ble 一、java異常類介紹。 Throwable: 有兩個重要的子類:Exception(異常)和 Error(錯誤),二者都是 Java 異常處理的重要子類,各自都包含大量子類。 有一篇比較好的b

    Java 異常處理

    nal fbo 失敗 類定義 參數 方法 ray 接下來 語法檢查 閱讀目錄 異常的概念 異常的體系結構 Java 異常的處理機制 異常處理的基本語法 異常鏈 自定義異常 總結 回到頂部 異常的概念 異常是程序中的一些錯誤,但並不是所有的錯誤都是異常,並且錯誤有時候

    實習培訓——Java異常處理(8)

    如何工作 出了 我們 個數 試圖 類對象 bject epo 很多 實習培訓——Java異常處理(8) Java 異常處理 異常是程序中的一些錯誤,但並不是所有的錯誤都是異常,並且錯誤有時候是可以避免的。 比如說,你的代碼少了一個分號,那麽運行出來結果是提示是錯誤 java

    spring boot 1.5.4 統一異常處理(九)

    springboot springboot1.5.4 springboot整合springdatajpa springboot集成jdbctemplate springboot異常處理 上一篇:springboot 1.5.4 配置文件詳解(八) 1 Spring Boot統一異

    Java——異常處理

    上一個 分別是 類型轉換 冒號 意思 參數 ack span log 1、java提供的異常不可能預見所有的問題,所以需要自己定義異常類,必須從已有的異常類繼承,最好選擇意思相近的異常類繼承。 class MyException extends Exception{}

    Java - 異常處理

    一個 普通 throw oid 基類 語句 內容 推薦 出現 主要內容: * Java 異常的概念。 * Java 異常的分類。 * 異常的捕獲和處理。 Q:Java 是如何對異常進行處理的? A:Java 中定義了很多異常類,這些類對應了各種各樣可能出現的異常事

    java異常處理的機制 java 架構師學習 java北京

    語句 變量 point try ray 多重 span throw 創建 在Java中,異常情況分為Exception(異常)和Error(錯誤)兩大類,Java異常通常是指程序運行過程中出現的非正常情況,如用戶輸入錯誤、除數為零、需要處理的文件不存在、數組下標越界等,對於

    Java入門提高篇】Day16 Java異常處理(下)

    http final 自定義異常 2個 輸入 也有 推薦 錯誤 num   今天繼續講解java中的異常處理機制,主要介紹Exception家族的主要成員,自定義異常,以及異常處理的正確姿勢。 Exception家族   一圖勝千言,先來看一張圖。   Excepti

    Java 異常處理的誤區和經驗總結

    ORC 進一步 相關 ror final 額外 檢測 業務 清理資源 一 異常分檢測異常和非檢測異常,異常的應用情景可以概括為以下: 調用代碼不能繼續執行,需要立即終止。出現這種情況的可能性太多太多,例如服務器連接不上、參數不正確等。這些時候都適用非檢測異常,不需要調用

    程序設計中關於Java 異常處理應註意的問題

    異常處理 try...catch Java 異常處理初識 下面程序,雖能運行,但當數據輸入有誤時程序不能正常結束,也就是說,程序本身沒有進行異常處理。 例題001 用Java編寫程序。輸入兩個整數,輸出它們的商。 import java.util.Scanner;public class MyAd

    深入理解Java異常處理機制 (籠統篇)

    throw 種類型 綜合 IV 算術 其它 wid all 作用 開篇 1.異常處理(Exception Handling):   就是一種解決這一問題的機制,能夠較好地處理程序不能正常運行的情況。 2.異常(Exception):   是程序在運行時可能出現的

    每日一題:Java異常處理

    增加 異常處理 int throwable 邏輯 現實 inter throws 運行時 什麽是異常 在理想情況下,程序總會運行在很完美的環境中,網絡不會終端,文件一定存在,程序不會有 BUG。但是,理想很豐滿,現實很骨幹,實際生產環境中,網絡可能會中斷,文件可能會找不到,

    Java異常處理總結

    tst error 有一個 ror 而是 阻止 cep 行處理 編碼 一、Java 異常繼承框架 Error: Error類對象由 Java 虛擬機生成並拋出,大多數錯誤與代碼編寫者所執行的操作無關。對於設計合理的應用程序來說,即使確實發生了錯誤,本質上也不應該試圖去處理

    java異常處理中的return和throw

    如果把return和throw放在一起,直接會提示錯誤。"Unreachable statement"(無法被執行). 然而finally卻可以成功騙過編譯器讓兩者並存(是不是可以算是編譯器的一個小bug呢),結果是後執行的會覆蓋前者。 finally如果有return會覆蓋cat

    java 異常處理之宣告丟擲異常

    java 異常處理宣告丟擲異常 2.宣告丟擲異常是Java中處理異常的第二種方式 2.宣告丟擲異常是Java中處理異常的第二種方式 如果一個方法(中的語句執行時)可能生成某種異常,但是並不能確定如何處理這種異常,則此方

    java 異常處理機制,throws與throw,try-catch-finally

    java 異常處理機制 1.Java異常處理 2.try-catch-finally的程式流程圖 3.關鍵解讀 4.demo 5.不捕獲異常時的情況 在編寫程式時,經常要在可能出現錯誤的地方