【Java】如何理解Java中的异常机制?
1 異常的概念
2 異常的分類
3 異常的產生過程
4 處理異常的方式
4.1 throw關鍵字
作用:在指定方法中拋出指定異常
使用格式:throw new xxxException(“異常產生原因”)
注意事項:
- 必須寫在方法內部
- new的對象要是Exception 或 Exception的子類
- 如果拋出指定的異常對象,必須處理這個異常對象。
- 如果創建的時RuntimeException或其子類,默認交給JVM處理(打印異常對象,中斷程序)
- 如果創建的時編譯異常,就必須處理這個異常,必須throws或者try-catch
小貼士:必須首先對方法傳遞來的參數進行合法性校驗,如果參數不合法,必須拋出異常,告知方法調用者,傳遞的參數有問題。
示例
運行時異常:NullPointerException
4.2 Objects非空判斷
Objects類的靜態方法
public static <T> T requireNonNull(T obj) {if (obj == null)throw new NullPointerException() ;return obj; }簡化非空判斷
public static void main(String[] args) {method(null);}public static void method(Object obj){Objects.requireNonNull(obj,"傳遞對象為空");}4.3 throws聲明異常
異常處理的第一種方式,交給別人處理
作用:當方法內部拋出異常對象時,必須處理異常對象,可以使用throws關鍵字處理,會把異常對象拋給方法調用者處理,自己不處理,交給他人處理,最終交給JVM處理。(JVM中斷處理)
使用方式:在方法聲明時使用
注意:
- 必須寫在方法聲明處
- 必須是Exception或其子類
- 拋出多個異常,聲明處要聲明多個異常,如果是父子異常,聲明父異常即可
- 調用了聲明異常的方法必須處理聲明的異常。throws拋出最終交給JVM處理或者try-catch定義異常處理邏輯。
編譯時異常:FileNotFoundException
public static void main(String[] args) throws FileNotFoundException {method("c:\\d.txt");}public static void method(String filename) throws FileNotFoundException {if(!filename.equals("c:\\\\a.txt")){throw new FileNotFoundException("文件路徑錯誤");}}FileNotFoundException extends IOException extends Exception
public static void main(String[] args) throws IOException {readFile("c:\\a.doc");}public static void readFile(String filename) throws IOException {if(!filename.endsWith(".txt")){throw new IOException("文件后綴不對");}}4.4 try-catch捕獲異常
異常處理的第二種方式,自己處理,程序不中斷
public static void main(String[] args) throws IOException {try{readFile("d:\\a.tx");}catch (IOException e){System.out.println("文件后綴有誤");}System.out.println("程序不中斷,后續代碼繼續執行");}public static void readFile(String filename) throws IOException{if(!filename.endsWith(".txt")){throw new IOException("文件后綴有誤");}System.out.println("讀取文件");}4.5 Throwable類中三個異常處理方法
- String getMessage()
打印Message: throw new IOException(Message);
public static void main(String[] args) {try{readFile("d:\\a.tx");}catch (IOException e){System.out.println(e.getMessage());}System.out.println("程序不中斷,后續代碼繼續執行");}public static void readFile(String filename) throws IOException{if(!filename.endsWith(".txt")){throw new IOException("文件后綴有誤");}System.out.println("讀取文件");}- String toString()
重寫Object類的toString
public static void main(String[] args){try{readFile("d:\\a.tx");}catch (IOException e){System.out.println(e.toString());}System.out.println("程序不中斷,后續代碼繼續執行");}public static void readFile(String filename) throws IOException{if(!filename.endsWith(".txt")){throw new IOException("文件后綴有誤");}System.out.println("讀取文件");}- void printStackTrace()
4.6 finally代碼塊
public static void main(String[] args){try {readFile("d:\\a.tx");} catch (IOException e) {e.printStackTrace();} finally {System.out.println("異常出現后依舊需要執行的代碼");}System.out.println("程序不中斷,后續代碼繼續執行");}public static void readFile(String filename) throws IOException{if(!filename.endsWith(".txt")){throw new IOException("文件后綴有誤");}System.out.println("讀取文件");}4.7 多異常捕獲
分別捕獲,分別處理
public static void main(String[] args) {int[] arr = {1,2,3};List<Integer> list = new ArrayList<>();list.add(1);try{System.out.println(arr[3]);}catch (ArrayIndexOutOfBoundsException e){e.printStackTrace();}try{System.out.println(list.get(1));}catch (IndexOutOfBoundsException e){e.printStackTrace();}System.out.println("后續代碼繼續執行...");}一次捕獲,多次處理
public static void main(String[] args) {try{int[] arr = {1,2,3};List<Integer> list = new ArrayList<>();System.out.println(arr[3]);list.add(1);System.out.println(list.get(1));}catch (ArrayIndexOutOfBoundsException e){e.printStackTrace();}catch (IndexOutOfBoundsException e){e.printStackTrace();}System.out.println("后續代碼繼續執行...");}
注意事項:一個try多個catch,catch中的異常變量如果有父子關系,子類異常變量必須寫在上面,否則會報錯。(XXXException has already been caught)
一次捕獲,一次處理
public static void main(String[] args) {try {int[] arr = {1, 2, 3};List<Integer> list = new ArrayList<>();System.out.println(arr[3]);list.add(1);System.out.println(list.get(1));}catch (Exception e){e.printStackTrace();}System.out.println("后續代碼繼續執行...");}運行時異常被拋出可以不處理。即不捕獲也不聲明拋出。
如果finally有return語句,永遠返回finally中的結果,避免該情況。
如果父類拋出了多個異常,子類重寫父類方法時,拋出和父類相同的異常或者是父類異常的子類或者不拋出異常。
父類方法沒有拋出異常,子類重寫父類該方法時也不可拋出異常。此時子類產生該異常,只能捕獲處理【try-catch】,不能聲明拋出。
5 自定義異常
- 自定義異常類一部都是以Exception結尾
- 必須繼承Exception(編譯期異常,要么try-catch要么throws)或者繼承RuntimeException(運行期異常交給JVM中斷處理)
模擬注冊操作
throws
public class Register {static String[] usernames = {"張三","李四","王五"};public static void main(String[] args) throws RegisterException {System.out.print("請輸入待注冊用戶名:");Scanner sc = new Scanner(System.in);String username = sc.next();checkUserName(username);System.out.println("恭喜,注冊成功!");}//繼承Exception是編譯期異常 throws 處理public static void checkUserName(String name) throws RegisterException {for(String n: usernames){if(n.equals(name)){throw new RegisterException("該用戶名已注冊");}}} }try-catch
public class Register {static String[] usernames = {"張三", "李四", "王五"};public static void main(String[] args) {System.out.print("請輸入待注冊用戶名:");Scanner sc = new Scanner(System.in);String username = sc.next();try {checkUserName(username);} catch (RegisterException e) {e.printStackTrace();return;}System.out.println("恭喜,注冊成功!");}//繼承Exception是編譯期異常 throws 處理public static void checkUserName(String name) throws RegisterException {for(String n: usernames){if(n.equals(name)){throw new RegisterException("該用戶名已注冊");}}} }總結
以上是生活随笔為你收集整理的【Java】如何理解Java中的异常机制?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android官方开发文档Trainin
- 下一篇: Pycharm使用远程服务器运行代码