異常 筆記目錄:(https://www.cnblogs.com/wenjie2000/p/16378441.html) 運行下麵的代碼,看看有什麼問題->引出異常和異常處理機制 public static void main(String[] args) { int num1 =10; int n ...
異常
筆記目錄:(https://www.cnblogs.com/wenjie2000/p/16378441.html)
運行下麵的代碼,看看有什麼問題->引出異常和異常處理機制
public static void main(String[] args) {
int num1 =10;
int num2 = 0;
int res = num1 / num2;//會報錯,除數不能為0
System.out.println("程式繼續運行....");
}
處理思路:
public class Test {
public static void main(String[] args) {
int num1 =10;
int num2 = 0;
//解讀
//1. num1 / num2 =>10/ 0
//2.當執行到num1 / num2因為 num2= 0,程式就會出現(拋出)異常ArithmeticException
//3.當拋出異常後,程式就退出,崩潰了,下麵的代碼就不在執行
//4.大家想想這樣的程式好嗎?不好,不應該出現了一個不算致命的問題,就導致整個系統崩潰
//5.java設計者,提供了一個叫異常處理機制來解決該問題
// int res = num1 / num2;
//如果程式員,認為一段代碼可能出現異常/問題,可以使用try-catch異常處理機制來解決
// 從而保證程式的健壯性
// 將該代碼塊->選中->快捷鍵ctrl + alt + t ->選中 try-catch
// 6.如果進行異常處理,那麼即使出現了異常,程式可以繼續執行
try {
int res = num1 / num2;
} catch (Exception e) {
// e.printStackTrace();
System.out.println("異常原因是:"+e.getMessage());
}
System.out.println("程式繼續運行....");
}
}
異常的概念
基本概念
Java語言中,將程式執行中發生的不正常情況稱為“異常”。(開發過程中的語法錯誤和邏輯錯誤不是異常)
執行過程中所發生的異常事件可分為兩大類
- Error(錯誤):Java虛擬機無法解決的嚴重問題。如:JVM系統內部錯誤、資源耗盡等嚴重情況。比如:StackOverflowError[棧溢出]和OOM(out of memory). Error是嚴重錯誤,程式會崩潰。
- Exception:其它因編程錯誤或偶然的外在因素導致的一般性問題,可以使用針對性的代碼進行處理。例如空指針訪問,試圖讀取不存在的文件,網路連接中斷等等,Exception 分為兩大類:運行時異常[程式運行時,發生的異常]和編譯時異常[編譯時,編譯器檢查出的異常]。
★異常體系圖
異常體系圖的小結
- 異常分為兩大類,運行時異常和編譯時異常。
- 運行時異常,編譯器檢查不出來。一般是指編程時的邏輯錯誤,是程式員應該避免其出現的異常。java.lang.RuntimeException類及它的子類都是運行時異常
- 對於運行時異常,可以不作處理,因為這類異常很普遍,若全處理可能會對程式的可讀性和運行效率產生影響
- 編譯時異常,是編譯器要求必須處置的異常。
常見的異常
常見的運行時異常
異常類 | 說明 |
---|---|
NullPointerException | 空指針異常 |
ArithmeticException | 數學運算異常 |
ArraylndexOutOfBoundsException | 數組下標越界異常 |
ClassCastException | 類型轉換異常 |
NumberFormatException | 數字格式不正確異常[] |
常見的運行時異常舉例
- NullPointerException空指針異常
當應用程式試圖在需要對象的地方使用null時,拋出該異常,看案例演示。
public static void main(String[] args) {
String name=null;
System.out.println(name.length());
}
-
ArithmeticException數學運算異常
當出現異常的遺算條件時,拋出此異常。例如,一個整數“除以零”時,拋出此類的一個實例,【前面最開始已經使用此案例,不再過多贅述】 -
ArraylndexOutOfBoundsException數組下標越界異常用非法索引訪問數組時拋出的異常。
如果索引為負或大於等於數組大小,則該索引為非法索引。
public static void main(String[] args) { int[] arr={1,2,5}; for (int i = 0; i <= 3; i++) { System.out.println(arr[i]); } }
-
ClassCastException類型轉換異常
當試圖將對象強制轉換為不是實例的子類時,拋出該異常。例如,以下代碼將生成一個ClassCastException
public class Test { public static void main(String[] args) { A b = new B();//向上轉型 B b2 = (B) b;//向下轉型,這裡是OK C c2 = (C) b;//這裡拋出ClassOastException } } class A {} class B extends A {} class C extends A {}
-
NumberFormatException數字格式不正確異常
當應用程式試圖將字元串轉換成一種數值類型,但該字元串不能轉換為適當格式時,拋出該異常=>使用異常我們可以確保輸入是滿足條件數字.
public static void main(String[] args) { String name = "韓順平教育"; //將String 轉成int int num = Integer.parseInt(name);//拋出NumberFormatException System.out.println(num); }
編譯異常
介紹
編譯異常是指在編譯期間,就必須處理的異常,否則代碼不能通過編譯。
常見的編譯異常
SQLException //操作資料庫時,查詢表可能發生異常
IOException//操作文件時,發生的異常
FileNotFoundException //當操作一個不存在的文件時,發生異常
ClassNotFoundException //載入類,而該類不存在時,異常
EOFException//操作文件,到文件末尾,發生異常
IllegalArguementException//參數異常
異常處理
基本介紹
異常處理就是當異常發生時,對異常處理的方式。
異常處理的方式
-
try-catch-finally
程式員在代碼中捕獲發生的異常,自行處理try { // 代碼/可能有異常 }catch(Exception e){ //捕獲到異常 //1.當異常發生時 //2系統將異常封裝成Exception對象e,傳遞給catch //3得到異常對象後,程式員,自己處理 //4.註意,如果沒有發生異常catch代碼塊不執行 }finally { //1.不管try代碼塊是否有異常發生,始終要執行finally //2.所以,通常將釋放資源的代碼,放在finally }
-
throws
將發生的異常拋出,交給調用者(方法)來處理,最頂級的處理者就是JVM- try-catch-finally和throws二選一
- 如果程式員沒做相應處理,沒有顯示是處理異常,預設throws
try-catch異常處理
try-catch方式處理異常說明
-
Java提供try和catch塊來處理異常。try塊用於包含可能出錯的代碼。catch塊用於處理try塊中發生的異常。可以根據需要在程式中有多個try..catch塊。
-
基本語法
try { //可疑代碼 //將異常生成對應的異常對象,傳遞給catch塊 }catch(異常){ //對異常的處理 } //沒有finally,語法是可以通過的
try-catch方式處理異常-註意事項
-
如果異常發生了,則異常發生後面的代碼不會執行,直接進入到catch塊.
-
如果異常沒有發生,則順序執行try的代碼塊,不會進入到catch.
-
如果希望不管是否發生異常,都執行某段代碼(比如關閉連接,釋放資源等)則使用finally {}
-
可以有多個catch語句,捕獲不同的異常(進行不同的業務處理),要求父類異常在後,子類異常在前,比如(Exception在後,NullPointerException在前),如果發生異常,只會匹配一個catch,【案例演示】
public static void main(String[] args) { //解讀 //1.如果try代碼塊有可能有多個異常 //2.可以使用多個catch分別捕獲不同的異常,相應處理 //3.要求子類異常寫在所面,父類異常寫在後面 try { String person = null; System.out.println(person.length());//NullPointerException int n1 = 10; int n2 = 0; int res = n1 / n2; //ArithmeticException } catch (NullPointerException e) { System.out.println("空指針異常=" + e.getMessage()); } catch (ArithmeticException e) { System.out.println("算術異常=" + e.getMessage()); } catch (Exception e) { System.out.println(e.getMessage()); } finally { } }
-
可以進行try-finally 配合使用,這種用法相當於沒有捕獲異常,因此程式會直接崩掉。應用場景,就是執行一段代碼,不管是否發生異常,都必須執行某個業務邏輯
public static void main(String[] args) { try { int n1 = 10; int n2 = 0; System.out.println(n1 / n2); } finally { System.out.println("執行了finally..");//無論是否會報錯都會執行 } System.out.println("程式繼續執行..");//因為上面報錯,finally執行後就強制停止運行,這行不執行 }
try-catch-finally執行順序小結
- 如果沒有出現異常,則執行try塊中所有語句,不執行catch塊中語句,如果有finally,最後還需要執行finally裡面的語句
- 如果出現異常,則try塊中異常發生後,try塊剩下的語句不再執行。將執行catch塊中的語句,如果有finally,最後還需要執行finally裡面的語句!
throws異常處理
基本介紹
-
如果一個方法(中的語句執行時)可能生成某種異常,但是並不能確定如何處理這種異常,則此方法應顯示地聲明拋出異常,表明該方法將不對這些異常進行處理,而由該方法的調用者負責處理。
-
在方法聲明中用throws語句可以聲明拋出異常的列表,throws後面的異常類型可以是方法中產生的異常類型,也可以是它的父類。
public void f2() throws FileNotFoundException,NullPointerException,ArithmeticException { //創建了一個文件流對象 //解讀: //1.這裡的異常是一個FileNotFoundException 編譯異常 // 2。使用前面講過的 try-catch-finally //3.使用throws,拋出異常,讓調用f2方法的調用者(方法)處理 //4. throws後面的異常類型可以是方法中產生的異常類型,也可以是它的父類 // 5. throws 關鍵字後也可以是異常列表,即可以拋出多個異常 FileInputStream fis = new FileInputStream("d://aa.txt"); }
註意事項和使用細節
- 對於編譯異常,程式中必須處理,比如try-catch 或者throws
- 對於運行時異常,程式中如果沒有處理,預設就是throws的方式處理[舉例]
- 子類重寫父類的方法時,對拋出異常的規定:子類重寫的方法,所拋出的異常類型要麼和父類拋出的異常一致,要麼為父類拋出的異常的類型的子類型[舉例]
- 在throws過程中,如果有方法 try-catch,就相當於處理異常,就可以不必throws
自定義異常
自定義異常的步驟
- 定義類:自定義異常類名(程式員自己寫)繼承Exception或RuntineException
- 如果繼承Exception,屬於編譯異常
- 如果繼承RuntimeException,屬於運行異常(一般來說,繼承RuntimeException)。
自定義異常的應用實例
當我們接收Person對象年齡時,要求範圍在18-120之間,否則拋出一個自定義異常(要求繼承RuntimeException),並給出提示信息。
public class Test {
public static void main(String[] args) {
int age = 180;
//要求範圍在18 -120之間,否則拋出一個自定義異常
if (!(age >= 18 && age <= 120)) {
//這裡我們可以通過構造器,設置信息
throw new AgeException("年齡需要在18~120之間");
}
System.out.println("你的年齡範圍正確。");
}
}
//自定義一個異常
// 解讀
//1.一般情況下,我們自定義異常是繼承 RuntimeException
//2.即把自定義異常做成運行時異常,好處時,我們可以使用預設的處理機制
//3.即比較方便
class AgeException extends RuntimeException {
public AgeException(String message) {//構造器
super(message);
}
}
throw和throws的對比
一覽表
意義 | 位置 | 後面跟的東西 | |
---|---|---|---|
throws | 異常處理的一種方式 | 方法聲明處 | 異常類型 |
throw | 手動生成異常對象的關鍵字 | 方法體中 | 異常對象 |