Java基礎(8)— 異常
阿新 • • 發佈:2020-07-30
異常機制
什麼是異常
-
實際工作中,遇到的情況不可能是非常完美的。比如:你寫的某個模組,使用者輸入不一定符合你的要求。你的程式要開啟某個檔案,這個檔案可能不存在或者檔案格式不對,你要讀取資料庫的資料,資料可能是空的等。我們的程式再跑著,記憶體或硬碟可能滿了。等等...
-
軟體程式在執行過程中,非常可能遇到剛剛提到的這些異常問題,我們叫異常,英文是:Exception,意思是例外。這些例外情況,或者叫異常,怎麼讓我們寫的程式做出合理的處理,而不至於程式崩潰
-
異常指程式執行中出現的不期而至的各種狀況,如:檔案找不到,網路連線失敗,非法引數等
-
異常發生在程式執行期間,它影響了正常的程式執行流程
-
要理解Java異常處理是如何工作的,你需要掌握以下三種類型的異常:
- 異常處理框架
- 檢查性異常:最具代表的檢查性異常是使用者錯誤或問題引起的異常,這是程式設計師無法預見的。例如要開啟一個不存在檔案時,一個異常就發生了,這些異常在編譯時不能被簡單地忽略
- 執行時異常:執行時異常是能被程式設計師避免的異常。與檢查性異常相反,執行時異常可以在編譯時被忽略。
- 錯誤ERROR:錯誤不是異常,而是脫離程式設計師控制的問題。錯誤在程式碼中通常被忽略。例如,當棧溢位時,一個錯誤就發生了,它們在編譯也檢查不到的。
異常體系結構
- Java把異常當作物件來處理,並定義一個基類 java.lang.Throwable 作為所有異常的超類
- 在Java API中已經定義了許多異常類,這些異常類分為兩大類,錯誤Error和異常Exception
-
Error
- Error類物件由Java虛擬機器生成並丟擲,大多數錯誤與程式碼編寫者所執行的操作無關
- Java虛擬機器執行錯誤(Virtual MachineError) ,當JVM不再有繼續執行操作所需的記憶體資源時,將出現OutOfMemoryError。這些異常發生時,Java虛擬機器(JVM) 一般會選擇執行緒終 止
- 還有發生在虛擬機器試圖執行應用時,如類定義錯誤(NoClassDefFoundError) 、連結錯誤 (LinkageError)。這些錯誤是不可查的,因為它們在應用程式的控制和處理能力之外,而且 絕大多數是程式執行時不允許出現的狀況
-
Exception
-
在Exception分支中有一個重要的子類RuntimeException (執行時異常)
-
ArrayIndexOutOfBoundsException (陣列下標越界)
-
NullPointerException (空指標異常)
-
ArithmeticException (算術異常)
-
MissingResourceException (丟失資源)
-
ClassNotFoundException (找不到類)
-
.... 這些異常是不檢查異常,程式中可以選擇捕獲處理,也可以不處理
-
-
這些異常一般是由程式邏輯錯誤引起的, 程式應該從邏輯角度儘可能避免這類異常的發生
-
-
Error和Exception的區別:
- Error通常是災難性的致命的錯誤,是程式無法控制和處理的,當出現這些異常時,Java虛擬機器(JVM)一般會選擇終止執行緒; Exception通常情況下是可以被程式處理的,並且在程式中應該儘可能的去處理這些異常
Java異常處理機制
-
丟擲異常
-
捕獲異常
-
異常處理五個關鍵字
- try 、catch、finally、throw、throws
public class Demo01 { public static void main(String[] args) { int a = 1; int b = 0; // System.out.println(a/b);//java.lang.ArithmeticException: / by zero try{ //try監控區 System.out.println(a/b); }catch(ArithmeticException e){ //捕獲異常 System.out.println("程式出現異常,變數b不能為0"); }finally{ //處理善後工作 System.out.println("finally"); } /* try catch 必須要有 finally 可以不要,假設IO,資源等關閉操作 */ } } public class Demo02 { public static void main(String[] args) { try{ new Demo02().a(); }catch(Error e){ System.out.println("Error"); //進入這個,異常只能從小到大的去捕獲 }catch (Exception e){ System.out.println("Exception"); }catch (Throwable e){ System.out.println("Throwable"); } finally{ System.out.println("finally"); } } public void a(){b();} public void b(){a();} } public class Demo03 { public static void main(String[] args) { int a = 1; int b = 0; //快捷鍵 Ctrl + Alt + T try { if(b == 0){ throw new ArithmeticException(); //主動丟擲異常 throw 什麼都沒有做,一般在方法中使用 } System.out.println(a/b); } catch (Exception e) { System.out.println("加入自己的邏輯..."); // System.exit(0);//結束程式 // e.printStackTrace(); }finally { } } //假設這個方法中處理不了這個異常,在方法上丟擲異常 public void test(int a, int b) throws ArithmeticException{ if(b == 0){ throw new ArithmeticException(); //主動丟擲異常 throw 什麼都沒有做 } } }
自定義異常
-
使用Java內建的異常類可以描述在程式設計時出現的大部分異常情況。除此之外,使用者還可以自定義異常。使用者自定義異常類,只需繼承Exception類即可
-
在程式中使用自定義異常類,大體可分為以下幾個步驟
- 建立自定義異常類
- 在方法中通過throw關鍵字丟擲異常物件
- 如果在當前丟擲異常的方法中處理異常,可以使用try-catch語句捕獲並處理;否則在方法的宣告處通過throws關鍵字指明要丟擲給方法呼叫者的異常,繼續進行下一步操作
- 在出現異常方法的呼叫者中捕獲並處理異常
//自定義異常類 public class MyException extends Exception{ //傳遞數字 > 10 private int detail; public MyException( int detail) { this.detail = detail; } //toString:異常的列印資訊 @Override public String toString() { return "MyException{" + "detail=" + detail + '}'; } } //應用 public class Test { //可能會存在異常的方法 static void test(int num) throws MyException{ System.out.println("傳遞的引數為:" + num); if(num > 10){ throw new MyException(num); //丟擲 } System.out.println("OK"); } public static void main(String[] args) { try { test(11); } catch (MyException e) { //增加一些處理異常的程式碼塊 System.out.println("MyException --> " + e); } } }
總結
- 處理執行時異常時,採用邏輯去合理的規避同時輔助 try-catch 處理
- 在多重catch塊後面,可以加一個catch(Exception)來處理可能會被遺漏的異常
- 對於不確定的程式碼,也可以加上 try-catch,處理潛在的異常
- 儘量去處理異常,切忌只時簡單的呼叫printStackTrace()去列印輸出
- 具體如何處理異常,要根據不同的業務需求和異常型別去解決
- 儘量新增finally語句塊去釋放佔用的資源