黑馬程序員--Java基礎學習筆記【異常處理】

 

 ------Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流! -------    

 

異常

    異常就是Java程序在運行過程中出現的導致程序無法正常運行的錯誤。

Java 中異常繼承體系,頂層的類

    java.lang.Throwable

    java.lang.Exception 所有異常的超類

       RuntimeException 運行時異常可以不處理

       RuntimeExceptioin非運行時異常必須捕獲處理

    java.lang.Error 所有錯誤的超類

 

異常處理機制

    當程序中拋出一個異常後,程序從程序中導致異常的代碼處跳出,java虛擬機檢測尋找和 try關鍵字匹配的處理該異常的 catch塊,如果找到,將控制權交到 catch塊中的代碼,然後繼續往下執行程序,try 塊中發生異常的代碼不會被重新執行。如果沒有找到處理該異常的 catch 塊,在所有的 finally 塊代碼被執行和當前線程所屬的ThreadGroup uncaughtException 方法被調用後,遇到異常的當前線程被中止。

 

異常處理

    Java語言中,使用 throw 關鍵字來引發異常。

    對異常處理的兩條途徑爲:

  1. 1.  使用 throws 拋出異常

  2. 2.  使用 try-catch 語句捕獲異常

  3. n  try-catch

try {

    可能出現異常的代碼

} catch(Exception e) {

    異常處理代碼

}

  • 多個 catch

每個 try 語句塊可以伴隨一個或多個 catch 語句,用於處理可能產生的不同類型的異常。catch 捕獲的異常類型由上至下的捕獲異常類型的順序應是子類到父類的。子類型異常在前,父類型異常在後,這樣的順序依次捕獲。否則編譯不通過。

  • finally 語句

爲異常處理提供一個統一的出口,使得在控制流程跳轉到程序其它部分以前,能夠對序的狀態作統一管理。無論 try 所指定的程序塊中是否拋出異常,finally 所指定的代碼都要被執行。通常在finally 語句中可以進行資源的釋放工作。

 

  • throw 關鍵字

寫在方法內部,拋出異常,後面寫 new 異常對象

    當程序發生錯誤而無法處理的時候,會拋出對應的異常對象,或用於自行拋出異常。

  • throws 關鍵字

寫在方法聲明上,告訴調用者處理異常,後面寫異常類類名

    方法中可能會因某些錯誤而引發異常,希望調用者處理,聲明方法會拋出異常。

method()throws Exception { // 聲明異常,讓調用者處理

    throw new Exception() // 拋出異常

}

  • 重寫方法時的throws

    如果使用繼承時,在父類的某個方法上聲明 throws 某些異常,而在子類中重新定義該方法時,

可以:

不處理異常(重新定義時不設定throws

可僅 throws 父類中聲明的部分異常

throws 父類方法中拋出異常的子類異常

不可以:

throws 出額外的異常

throws 父類方法中拋出異常的父類異常

概括爲:父類方法中拋出異常,子類重寫可拋可不拋;父類不拋,子類不能拋出。

 

異常的分類

    ——運行時異常RuntimeException ,又稱非檢測異常

    直接或間接繼承RuntimeException 的異常。不受編譯器檢查與處理或聲明規則的限制,在發生此類異常時,不一定非要採取處理操作,編譯器不會檢查是否解決異常。

    ——非運行時異常又稱可檢測異常,編譯時異常

    是指除了RuntimeException 以外的其他異常,是程序有邏輯錯誤。可檢測異常經編譯器驗證,對於聲明拋出異常的任何方法,編譯器將強制執行處理或聲明規則,不捕捉這個異常,編譯器就通不過,不允許編譯。

    Java編譯器要求方法必須聲明拋出可能發生的非運行時異常,但是不要求必須聲明拋出未被捕獲的運行時異常。

 

——常見的運行時異常:

    IllegalArgumentException 不合法參數異常:向方法傳遞一個不合法或不正確參數

NullPointerException空指針異常:當操作一個空引用時會出現此異常

    NumberFormatException 數字格式化異常:試圖將字符串轉換成一種數值類型,但該字符串不能轉換爲適當格式時,拋出該異常

    ClassCastException 類型轉換異常:強制類型轉換類型不匹配時出現此異常

    ArrayIndexOutOfBoundsException 數組下標越界異常:當使用一個不存在的數組下標時出現此異常。

    ArithmeticException 數學異常:當出現異常的運算條件時出現此異常

——常見的非運行時異常:

    SQLException 提供關於數據庫訪問錯的異常

    IOException 當發生某種 I/O 異常時,拋出此異常

    ClassNotFoundException 當應用程序試圖使用 Class 類中的 forName 方法、loadClass 方法時,拋出該異常

 

Throwable 中的方法

    getMessage() // 獲取異常信息,返回字符串

    toString() // 獲取異常類名和異常信息,返回字符串

    printStackTrace() // 獲取異常類名和異常信息及出現的位置,輸出執行堆棧信息

    printStackTrace(PrintStream s) // 將異常內容保存在日誌文件中

 

自定義異常

    爲了更加精準地捕獲和處理異常以呈現更好的用戶體驗,需要開發者自定義異常。

    繼承 Exception 自定義異常,定義好自定義異常後,可以通過IDE生成相應構造方法。

    class 自定義異常類名 extendsException {

       …

}

 

編譯時期異常和運行時期異常的區別:

    編譯時期異常:拋出的異常類,不是RuntimeException類或者其子類

    調用者,調用一個拋出異常的方法,如果不處理,編譯失敗

    異常是編譯器最後檢測的問題

 

    運行時期異常:拋出的異常類,是RuntimeException類和其子類

    拋出的是運行時期異常,凡是方法內部拋出的異常是運行時期,方法的聲明上,無需throws,對應方法的調用者,就不需要處理異常。

 

    運行時期異常的設計思想:

    運行時期異常,在程序的運行中,是不能發生的,如果真的發生了,請程序人員停止程序,修改源代碼,運行時期異常一旦發生,後面的代碼就沒有運行的必要了。

 

finally 的特點及作用

    特點:被 finally 控制的語句體一定會執行,在return 返回值之前執行

    特殊情況:在執行finally之前jvm 退出(如System.exit(0)),線程死亡,關閉CPU

    作用:釋放資源(I/O 操作和數據庫操作)

 

packagecn.itcast;

 

/*

 * finally 語句塊不應該出現應該出現return

 * return ret 最好是其他語句來處理相關邏輯

 *

 * 正確運行結果是:

 *  i= 2

 *  i= 1

 *  testEx2, catch exception

 *  testEx2, finally; return value = false

 *  testEx1, finally; return value = false

 *  testEx, finally; return value = false

 */

publicclass TestException {

 

    public TestException() {

    }

 

    boolean testEx() throws Exception {

       booleanret = true;

       try {

           ret = textEx1(); // 接收返回值false

       } catch (Exception e) {

           System.out.println("testEx,cathch exception");

           ret = false;

           throwe;

       } finally {

           System.out.println("testEx,finally; return value= " + ret); //false

           returnret; // false

       }

    }

 

    boolean textEx1() throws Exception {

       booleanret = true;

       try {

           ret = textEx2(); // 接收返回值false

           if (!ret) {

              returnfalse;

           }

           System.out.println("testEx1,at the end of try");

           returnret;

       } catch (Exception e) {

           System.out.println("testEx1,cathch exception");

           ret = false;

           throwe;

       } finally {

           System.out.println("testEx1,finally; return value= " + ret); //false

           returnret; // try塊中已有返回值,此爲無效語句

       }

    }

 

    boolean textEx2() throws Exception {

       booleanret = true;

       try {

           intb = 12;

           intc;

           for (inti = 2; i>= -2; i--) {

              c= b / i;

              System.out.println("i=" + i);// 2, 1

           }

           returntrue; // 上面發生異常,此句未執行

       } catch (Exception e) {

           System.out.println("testEx2,catch exception");

           ret = false;

           throwe;

       } finally {

           System.out.println("testEx2,finally; return value= " + ret); //catch語句中賦值false

           returnret; // false

       }

    }

 

    publicstaticvoid main(String[] args) {

       TestExceptiontestException1 = newTestException();

       try {

           testException1.testEx();

//         System.out.println(testException1.testEx());// false

       } catch (Exception e) {

           e.printStackTrace();

       }

    }

 

}

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章