Java基礎 第三節 第十九課
異常的處理
概述
拋出異常
使用
Objects 非空判斷
聲明異常 throws
捕獲異常 try...catch
代碼展示
獲取異常信息
finally 代碼塊
代碼演示
異常注意事項
總結
概述
Java 異常處理的五個關鍵字: try, catch, finally, throw, throws.
拋出異常
在編寫程序時, 我們必須要考慮程序出現問題的情況. 比如, 在定義方法是=時, 方法需要接受參數. 那么, 當調用方法使用接受到參數時, 首先需要先對參數數據進行合法的判斷. 若數據不合法, 就應該告訴調用者, 傳遞合法的數據進來. 這是需要使用拋出異常的方式來告訴調用者.
在 Java 中, 提供了一個 throw 關鍵字, 它用來拋出一個指定的異常對象. 那么, 拋出一個異常具體如何操作呢?
創建一個異常對象, 封裝一些提示信息 (信息可以自己編寫)
需要將這個異常對象告知給調用正則. 怎么告知呢? 怎么將這個異常對象傳遞到調用者處呢? 通過關鍵字 throw 就可以完成. throw 異常對象.
使用
throws 用在方法內, 用來拋出一個異常對象, 將這個異常對象傳遞到調用者處, 并結束當前方法的執行.
使用格式:
throw new 異常類名(參數);
1
例如:
throw new NullPointerException("要訪問的arr數組不存在"); throw new ArrayIndexOutOfBoundsException("該索引在數組中不存在,已超出范圍");
1
2
學習完拋出異常的格式后, 我們通過下面程序演示下 throw 的使用. 代碼如下:
public class Test { public static void main(String[] args) { // 創建一個數組 int[] array = {1, 2, 3, 4, 5, 6}; // 根據索引找到對應的元素 int index = 6; int element = getElement(array, index); } /** * @param array 傳入的int數組 * @param index 需要查找的index * @return 返回指定索引的值 */ public static int getElement(int[] array, int index) { // 判斷是否越界 if (index < 0 || index > array.length - 1) { /* 判斷條件如果滿足, 方執行完throw拋出異常對象后, 方法已經無法繼續運算 這是就會結束當前方法的執行, 并將異常告知給調用者. 這時就需要通過異常來解決 */ throw new ArrayIndexOutOfBoundsException("小哥哥, 索引越界了~~"); } int element = array[index]; return element; } } 調試輸出: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 小哥哥, 索引越界了~~ at Test41.getElement(Test41.java:22) at Test41.main(Test41.java:7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
注意:
如果產生了問題, 我們就會 throw 將問題描述類即異常進行拋出, 也就是將問題返回給該方法的調用者
那么對于調用者來說, 該怎么處理呢?
一種是進行捕獲處理, 另一種就是繼續講問題聲明出去, 使用 throws 聲明處理出去, 使用 throws 聲明處理
Objects 非空判斷
還記得我們學習過一個類 Objects 嗎, 曾經提到過它由一些靜態的實用方法組成, 這些方法是 null-save (空指針安全的) 或 null-tolerant (容忍空指針的). 那么在它的源碼中, 對對象為 null 的值進行了拋出異常操作.
public static
查看源碼發現這里對為 null 的進行了拋出異常操作:
public static
1
2
3
4
5
6
聲明異常 throws
聲明異常: 將問題標識出來, 報告給調用者. 如果方法內通過 throw 拋出了編譯時異常, 而沒有捕獲處理 (稍后講解該方式). 那么必須通過 throws 進行聲明, 讓調用者去處理.
關鍵字 throws 運用于方法聲明之上, 同于表示放棄方法不處理異常, 而是提醒該方法的調用者來處理異常. (拋出異常)
聲明異常格式:
修飾符 返回值類型 方法名(參數) throws 異常類名1,異常類名2…{ }
1
聲明異常的代碼演示:
import java.io.FileNotFoundException; public class Test { public static void main(String[] args) throws FileNotFoundException { read("a.txt"); } // 如果定義功能有時間發生需要報告給調用者. 可以通過在方法上面throws關鍵字進行聲明 public static void read(String path) throws FileNotFoundException { if(!path.equals("a.txt")){ // 如果不是a.txt 這個文件 // 我假設如果a.txt認為該文件不存在是一個錯誤也就是異常throw throw new FileNotFoundException("文件不存在"); } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
捕獲異常 try…catch
如果異常出現的話, 會立刻終止程序, 所以我們得處理異常:
該方法不處理, 而是聲明拋出, 有該方法調用者來處理 (throws)
在方法中使用 try-catch 的語句塊來處理異常.
try-catch 的方式就是捕獲異常: Java 中對異常有針對性的語句進行捕獲, 可以對出現的異常進行制定方式的處理.
捕獲異常語法如下:
try{ 編寫可能會出現異常的代碼 }catch(異常類型 e){ 處理異常的代碼 //記錄日志/打印異常信息/繼續拋出異常 }
1
2
3
4
5
6
try: 該代碼塊中編寫可能產生異常的代碼.
catch: 用來進行某種異常的捕獲, 實現對捕獲到的異常進行處理.
代碼展示
import java.io.FileNotFoundException; public class Test44 { public static void main(String[] args) { try { read("a.txt"); } catch (FileNotFoundException e) { System.out.println(e); } System.out.println("over"); } // 如果定義功能有時間發生需要報告給調用者. 可以通過在方法上面throws關鍵字進行聲明 public static void read(String path) throws FileNotFoundException { if (!path.equals("a.txt")) { // 如果不是a.txt 這個文件 // 我假設如果a.txt認為該文件不存在是一個錯誤也就是異常throw throw new FileNotFoundException("文件不存在"); } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
注: try 和 catch 都不能單獨使用, 必須連用.
獲取異常信息
如何獲取異常信息?
Throwable 類中定義了一些查看方法:
public String getMessage(): 獲取異常的描述信息, 原因 (提示給用戶的時候, 就提示錯誤原因)
public String toString(): 獲取異常的類型和異常描述信息 (不用)
public void printStackTrace(): 打印異常的跟蹤棧的信息并輸出到控制臺
注: 包含了異常的類型, 異常的原因, 還包括異常出現的wiz, 在開發和調試階段, 都得使用printStackTrace
finally 代碼塊
finally: 有一些特定的代碼無論異常是否發生, 都需要執行. 另外, 因為異常會引發程序跳轉, 導致有些語句執行不到. 而 finally 就是解決這個問題的, 在 finally 代碼塊中存放的代碼都是一定會被執行的.
什么時候的代碼必須最終執行?
當我們在 try 語句塊中打開了一些物理資源 (磁盤文件/網絡連接/數據庫連接等). 我們都得在使用完之后, 最終關閉打開的資源.
比如我們之后學習的 IO 流中, 當打開了一個關聯的文件的資源, 最后程序不管結果如何, 都需要把這個資源關閉掉.
代碼演示
import java.io.FileNotFoundException; public class Test45 { public static void main(String[] args) { try { read("a.txt"); } catch (FileNotFoundException e) { //抓取到的是編譯期異常, 拋出去的是運行期 throw new RuntimeException(e); } finally { System.out.println("不管程序怎樣, 這里都將會被執行!"); } System.out.println("over"); } /* * * 我們當前的這個方法中有異常有編譯期異常 */ public static void read(String path) throws FileNotFoundException { if (!path.equals("a.txt")) {//如果不是 a.txt這個文件 // 我假設 如果不是a.txt, 認為該文件不存在, 是一個錯誤也就是異常, throw throw new FileNotFoundException("文件不存在"); } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
注: 當只有在 try 或者 catch 中調用退出 JVM 的相關方法, 此時 finally 才不會執行, 否則finally 永遠會執行.
異常注意事項
多個異常使用捕獲又該如何處理呢?
多個異常分別處理
多個異常一次捕獲, 多次處理
多個異常一次捕獲一次處理
一般我們是使用一次捕獲多次處理的方式, 格式如下:
try{ 編寫可能會出現異常的代碼 }catch(異常類型A e){ 當try中出現A類型異常,就用該catch來捕獲. 處理異常的代碼 //記錄日志/打印異常信息/繼續拋出異常 }catch(異常類型B e){ 當try中出現B類型異常,就用該catch來捕獲. 處理異常的代碼 //記錄日志/打印異常信息/繼續拋出異常 }
1
2
3
4
5
6
7
8
9
注: 這種異常處理方式, 要求多個 catch 中的異常不能相同, 并且若 catch 中的多個異常之間有子類和父類異常的關系, 那么子類異常要求在上面的 catch 處理, 魚類異常在下面的 catch 處理.
總結
運行時異常被拋出可以不處理, 即不捕獲也不聲明拋出
如果 finally 有 return 語句, 永遠返回 finally 中的結果, 避免該情況
如果父類拋出了多個異常, 子類重寫父類方法時, 拋出和父類相同的異?;蛘呤歉割惖淖宇惢蛘卟粧伋霎惓?/p>
父類方法沒有拋出異常, 子類重寫父類方法時也不可拋出異常, 此時子類產生該異常, 只能捕獲, 不能聲明拋出
Java
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。