異常的概念 異常,就是不正常的意思。在生活中:醫生說,你的身體某個部位有異常,該部位和正常相比有點不同,該部位的功能將受影響.在程式中的意思就是:指的是程式在執行過程中,出現的非正常的情況,終會導致JVM的非正常停止 註意:在Java等面向對象的編程語言中,異常本身是一個類,產生異常就是創建異常對象 ...
異常的概念
異常,就是不正常的意思。在生活中:醫生說,你的身體某個部位有異常,該部位和正常相比有點不同,該部位的功能將受影響.在程式中的意思就是:指的是程式在執行過程中,出現的非正常的情況,終會導致JVM的非正常停止
註意:在Java等面向對象的編程語言中,異常本身是一個類,產生異常就是創建異常對象並拋出了一個異常對象。Java處理異常的方式是中斷處理、異常指的並不是語法錯誤,語法錯了,編譯不通過,不會產生位元組碼文件,根本不能運行.
異常體系
異常機制其實是幫助我們找到程式中的問題,異常的根類是 java.lang.Throwable ,其下有兩個子類: java.lang.Error 與 java.lang.Exception ,平常所說的異常指 java.lang.Exception
Throwable體系
Error:嚴重錯誤Error,無法通過處理的錯誤,只能事先避免,好比絕症。
Exception:表示異常,異常產生後程式員可以通過代碼的方式糾正,使程式繼續運行,是必須要處理的。比如感冒、闌尾炎
Throwable中的常用方法
public void printStackTrace() :列印異常的詳細信息。 包含了異常的類型,異常的原因,還包括異常出現的位置,在開發和調試階段,都得使用printStackTrace。
public String getMessage() :獲取發生異常的原因。 提示給用戶的時候,就提示錯誤原因。
public String toString() :獲取異常的類型和異常描述信息(不用)。
異常(我們平常所說的異常就是Exception)的分類
編譯時期異常:checked異常。在編譯時期,就會檢查,如果沒有處理異常,則編譯失敗。(如日期格式化異常)
運行時期異常:runtime異常。在運行時期,檢查異常.在編譯時期,運行異常不會編譯器檢測(不報錯)。(如數學異常)
異常的處理
Java異常處理的五個關鍵字:try、catch、finally、throw、throws
拋出異常throw
在java中,提供了一個throw關鍵字,它用來拋出一個指定的異常對象
1. 創建一個異常對象。封裝一些提示信息(信息可以自己編寫)。
2. 需要將這個異常對象告知給調用者。怎麼告知呢?怎麼將這個異常對象傳遞到調用者處呢?通過關鍵字throw 就可以完成。throw 異常對象。
throw用在方法內,用來拋出一個異常對象,將這個異常對象傳遞到調用者處,並結束當前方法的執行
使用格式:throw new 異常類名(參數);
1 package demosummary.exception;
2
3 public class ThrowDemo {
4 public static void main(String[] args) {
5 //創建數組
6 int[] arr = {2, 4, 6, 8};
7 //根據索引找元素
8 int index = 4;
9 int element = getElement(arr, index);
10 System.out.println(element);
11 System.out.println( "over");
12 }
13
14 /*
15 根據索引找到元素
16 */
17 private static int getElement(int[] arr, int index) {
18 //判斷是否索引越界異常
19 if (index < 0 || index > arr.length - 1) {
20 /*判斷條件如果滿足,當執行完throw拋出異常對象後,方法已經無法繼續運算
21 這時就會結束當前方法的執行,並將異常告知給調用者。這時就需要通過異常來解決
22 */
23 throw new ArrayIndexOutOfBoundsException("哥們,角標越界了~~~");
24 }
25 int element = arr[index];
26 return element;
27 }
28 }
Objects非空判斷
public static <T> T requireNonNull(T obj) :查看指定引用對象不是null
1 package demosummary.exception;
2
3 public class Objects非空判斷 {
4 public static void main(String[] args) {
5 Integer a = null;
//調用方法reqireNonNull
6 requireNonNull(a);
7 }
8
9 public static <T> T requireNonNull(T obj) {
10 //判斷是否為空
11 if (obj == null) {
12 throw new NullPointerException();
13 }
14 return obj;
15 }
16
17 /**
18 * 執行結果
19 * Exception in thread "main" java.lang.NullPointerException
20 * at demosummary.exception.Objects非空判斷.requireNonNull(Objects非空判斷.java:11)
21 * at demosummary.exception.Objects非空判斷.main(Objects非空判斷.java:6)
22 */
23 }
聲明異常throws
聲明異常:將問題標識出來,報告給調用者。如果方法內通過throw拋出了編譯時異常,而沒有捕獲處理(稍後講 解該方式),那麼必須通過throws進行聲明,讓調用者去處理。
關鍵字throws運用於方法聲明之上,用於表示當前方法不處理異常,而是提醒該方法的調用者來處理異常(拋出異常).
格式:修飾符 返回值類型 方法名(參數) throws 異常類名1,異常類名2…{ }
1 package demosummary.exception;
2
3 import java.io.FileNotFoundException;
4 import java.io.IOException;
5
6 public class ThrowsDemo {
7 public static void main(String[] args) throws IOException {
8 read("a.txt");
9 }
10
11 public static void read(String path) throws FileNotFoundException,IOException{
12 if (!path.equals("a.txt")) {
13 /*
14 如果不是a.txt這個文件,則認為該文件不存在,是一個錯誤,也就是一個異常 throw
15 */
16 throw new FileNotFoundException("文件不存在");
17 }
18 if (!path.equals("b.txt")) {
19 throw new IOException();
20 }
21 }
22 }
捕獲異常try…catch
如果異常出現的話,會立刻終止程式,所以我們得處理異常:
1. 該方法不處理,而是聲明拋出,由該方法的調用者來處理(throws)。
2. 在方法中使用try-catch的語句塊來處理異常。
try-catch的方式就是捕獲異常。
捕獲異常:Java中對異常有針對性的語句進行捕獲,可以對出現的異常進行指定方式的處理。
格式:
try{
編寫可能會出現異常的代碼
}catch(異常類型 e){
處理異常的代碼
//記錄日誌/列印異常信息/繼續拋出異常
}
try:該代碼塊中編寫可能產生異常的代碼。
catch:用來進行某種異常的捕獲,實現對捕獲到的異常進行處理
註意:try和catch都不能單獨使用,必須連用
1 package demosummary.exception;
2
3 import java.io.FileNotFoundException;
4 import java.io.IOException;
5
6 public class ThrowsDemo {
7 public static void main(String[] args) {
8 //當有異常產生時,我們必須要處理,要麼聲明,要麼捕獲
9 try {
10 read("a.txt");
11 } catch (FileNotFoundException e) {
12 //try中拋出什麼異常,在括弧中就定義什麼異常類型
13 e.printStackTrace();
14 }
15 System.out.println("over");
16 }
17
18 public static void read(String path) throws FileNotFoundException{
19 if (!path.equals("a.txt")) {
20 /*
21 如果不是a.txt這個文件,則認為該文件不存在,是一個錯誤,也就是一個異常 throw
22 */
23 throw new FileNotFoundException("文件不存在");
24 }
25 }
26 }
public String getMessage() :獲取異常的描述信息,原因(提示給用戶的時候,就提示錯誤原因。
public String toString() :獲取異常的類型和異常描述信息(不用)。
public void printStackTrace() :列印異常的跟蹤棧信息並輸出到控制台。
finally 代碼塊
finally:有一些特定的代碼無論異常是否發生,都需要執行。另外,因為異常會引發程式跳轉,導致有些語句執行 不到。而finally就是解決這個問題的,在finally代碼塊中存放的代碼都是一定會被執行的。
finally的語法: try...catch....finally:自身需要處理異常,終還得關閉資源。(註意:finally不能單獨使用)
1 package demosummary.exception;
2
3 import java.io.FileNotFoundException;
4
5 public class TryCatchFinally異常處理 {
6 public static void main(String[] args) {
7 //當有異常產生時,我們必須要處理,要麼聲明,要麼捕獲
8 try {
9 read("a.txt");
10 } catch (FileNotFoundException e) {
11 //try中拋出什麼異常,在括弧中就定義什麼異常類型
12 e.printStackTrace();
13 }finally {
14 System.out.println("不管程式怎樣,這裡都將會被執行。");
15 }
16 System.out.println("over");
17 }
18
19 public static void read(String path) throws FileNotFoundException{
20 if (!path.equals("a.txt")) {
21 /*
22 如果不是a.txt這個文件,則認為該文件不存在,是一個錯誤,也就是一個異常 throw
23 */
24 throw new FileNotFoundException("文件不存在");
25 }
26 }
27 }
當只有在try或者catch中調用退出JVM的相關方法,此時finally才不會執行,否則finally永遠會執行。
異常註意事項
多個異常使用捕獲又該如何處理呢?
1. 多個異常分別處理。
2. 多個異常一次捕獲,多次處理。
3. 多個異常一次捕獲一次處理。
一般我們是使用一次捕獲多次處理方式,格式如下:
try{
編寫可能會出現異常的代碼
}catch(異常類型A e){ 當try中出現A類型異常,就用該catch來捕獲.
處理異常的代碼
//記錄日誌/列印異常信息/繼續拋出異常
}catch(異常類型B e){ 當try中出現B類型異常,就用該catch來捕獲.
處理異常的代碼
//記錄日誌/列印異常信息/繼續拋出異常
}
註意:這種異常處理方式,要求多個catch中的異常不能相同,並且若catch中的多個異常之間有子父類異 常的關係,那麼子類異常要求在上面的catch處理,父類異常在下麵的catch處理。
運行時異常被拋出可以不處理。即不捕獲也不聲明拋出。
如果finally有return語句,永遠返回finally中的結果,避免該情況.
如果父類拋出了多個異常,子類重寫父類方法時,拋出和父類相同的異常或者是父類異常的子類或者不拋出異 常。
父類方法沒有拋出異常,子類重寫父類該方法時也不可拋出異常。此時子類產生該異常,只能捕獲處理,不能聲明拋出