日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java异常处理教程(包含示例和最佳实践)

發(fā)布時間:2023/12/3 java 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java异常处理教程(包含示例和最佳实践) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

異常是可能在程序執(zhí)行期間發(fā)生的錯誤事件,它會破壞其正常流程。 Java提供了一種健壯且面向對象的方式來處理異常情況,稱為Java異常處理 。 我們將在本教程中研究以下主題。

  • Java異常處理概述
  • 異常處理關鍵字
  • 異常層次
  • 有用的異常方法
  • Java 7自動資源管理和捕獲塊改進
  • 創(chuàng)建自定義異常類
  • 異常處理最佳實踐
  • Java異常處理概述

    我們不喜歡異常,但是我們總是要處理它們,好消息是Java異常處理框架非常健壯,易于理解和使用。 異??赡茉从诟鞣N情況,例如用戶輸入的錯誤數據,硬件故障,網絡連接故障,數據庫服務器關閉等。在本節(jié)中,我們將學習如何在Java中處理異常。

    Java是一種面向對象的編程語言,只要在執(zhí)行一條語句時發(fā)生錯誤,就會創(chuàng)建一個異常對象 ,然后程序的正常流程會停止, JRE會設法找到可以處理引發(fā)異常的人。 異常對象包含許多調試信息,例如方法層次結構,發(fā)生異常的行號,異常類型等。當方法中發(fā)生異常時,將調用創(chuàng)建異常對象并將其移交給運行時環(huán)境的過程。 “拋出異?!?/strong> 。

    運行時一旦接收到異常對象,它將嘗試查找該異常的處理程序。 異常處理程序是可以處理異常對象的代碼塊。 查找異常處理程序的邏輯很簡單–在發(fā)生錯誤的方法中開始搜索,如果找不到合適的處理程序,則移至調用方方法,依此類推。 因此,如果方法調用堆棧為A-> B-> C且方法C中引發(fā)了異常,則對適當處理程序的搜索將從C-> B-> A轉移。 如果找到合適的異常處理程序,則將異常對象傳遞給該處理程序以對其進行處理。 據說處理程序正在“捕獲異?!?/strong> 。 如果找不到合適的異常處理程序,則程序終止有關異常的打印信息。

    請注意,Java異常處理是僅用于處理運行時錯誤的框架,異常處理框架不處理編譯時錯誤。

    我們在Java程序中使用特定的關鍵字來創(chuàng)建異常處理程序塊,接下來我們將研究這些關鍵字。

    異常處理關鍵字

    Java提供了用于異常處理目的的特定關鍵字,我們將首先照顧它們,然后編寫一個簡單的程序,展示如何使用它們進行異常處理。

  • throw –我們知道,如果發(fā)生任何異常,將創(chuàng)建一個異常對象,然后Java運行時開始處理以處理它們。 有時我們可能想在代碼中顯式生成異常,例如,在用戶身份驗證程序中,如果密碼為null,則應向客戶端拋出異常。 throw關鍵字用于向運行時拋出異常以進行處理。
  • throws –當我們在方法中拋出任何異常而不對其進行處理時,我們需要在方法簽名中使用throws關鍵字,以使調用程序知道該方法可能拋出的異常。 調用者方法可以處理這些異常,也可以使用throws關鍵字將其傳播到其調用者方法。 我們可以在throws子句中提供多個異常,它也可以與main()方法一起使用。
  • try-catch –我們在代碼中使用try-catch塊進行異常處理。 try是塊的開始,catch是try塊的末尾,用于處理異常。 我們可以使用try捕獲多個catch塊,并且try-catch塊也可以嵌套。 catch塊需要一個應為Exception類型的參數。
  • 最終 –最終塊是可選的,只能與try-catch塊一起使用。 由于異常會暫停執(zhí)行過程,因此我們可能會打開一些不會關閉的資源,因此可以使用finally塊。 無論是否發(fā)生異常,finally塊都會始終執(zhí)行。
  • 讓我們看一個簡單的程序,顯示Java中的異常處理。

    package com.journaldev.exceptions;import java.io.FileNotFoundException; import java.io.IOException;public class ExceptionHandling {public static void main(String[] args) throws FileNotFoundException, IOException {try{testException(-5);testException(-10);}catch(FileNotFoundException e){e.printStackTrace();}catch(IOException e){e.printStackTrace();}finally{System.out.println("Releasing resources"); }testException(15);}public static void testException(int i) throws FileNotFoundException, IOException{if(i < 0){FileNotFoundException myException = new FileNotFoundException("Negative Integer "+i);throw myException;}else if(i > 10){throw new IOException("Only supported for index 0 to 10");}}}

    上面程序的輸出是:

    java.io.FileNotFoundException: Negative Integer -5at com.journaldev.exceptions.ExceptionHandling.testException(ExceptionHandling.java:24)at com.journaldev.exceptions.ExceptionHandling.main(ExceptionHandling.java:10) Releasing resources Exception in thread "main" java.io.IOException: Only supported for index 0 to 10at com.journaldev.exceptions.ExceptionHandling.testException(ExceptionHandling.java:27)at com.journaldev.exceptions.ExceptionHandling.main(ExceptionHandling.java:19)

    注意,testException()方法使用throw關鍵字引發(fā)異常,方法簽名使用throws關鍵字使調用者知道它可能引發(fā)的異常類型。 在main()方法中,我正在使用main()方法中的try-catch塊來處理異常,當我不處理它時,我將通過main方法中的throws子句將其傳播到運行時。 注意,由于異常,永遠不會執(zhí)行testException(-10) ,然后在try-catch塊執(zhí)行后再執(zhí)行finally塊。 printStackTrace()是Exception類中的一種有用方法,用于調試目的。

    • 沒有try語句,我們不能有catch或finally子句。
    • 一個try語句應該具有catch塊或finally塊,它可以同時具有兩個塊。
    • 我們不能在try-catch-finally塊之間編寫任何代碼。
    • 一個try語句可以包含多個catch塊。
    • try-catch塊可以類似于if-else語句進行嵌套。
    • 我們只有一個帶有try-catch語句的finally塊。

    異常層次

    如前所述,當引發(fā)任何異常時,將創(chuàng)建一個異常對象 。 Java異常是分層的, 繼承用于對不同類型的異常進行分類。 Throwable是Java異常層次結構的父類,它具有兩個子對象–錯誤和異常。 異常進一步分為檢查異常和運行時異常。

  • 錯誤 :錯誤是超出應用程序范圍的特殊情況,無法預見并從中恢復,例如硬件故障,JVM崩潰或內存不足錯誤。 這就是為什么我們有一個單獨的錯誤層次結構,我們不應該嘗試處理這些情況。 一些常見的錯誤是OutOfMemoryError和StackOverflowError。
  • 檢查異常 :檢查異常是我們可以在程序中預期并嘗試從程序中恢復的異常情況,例如FileNotFoundException。 我們應該捕獲該異常,并向用戶提供有用的消息,并正確記錄下來以進行調試。 Exception是所有Checked Exceptions的父類,如果要拋出一個Checked異常,則必須在同一方法中捕獲它,否則必須使用throws關鍵字將其傳播給調用方。
  • 運行時異常 :運行時異常是由不良編程引起的,例如,嘗試從數組中檢索元素。 在嘗試檢索元素之前,我們應該先檢查數組的長度,否則它可能在運行時引發(fā)ArrayIndexOutOfBoundException 。 RuntimeException是所有運行時異常的父類。 如果我們在方法中引發(fā)任何運行時異常,則無需在方法簽名throws子句中指定它們。 更好的編程可以避免運行時異常。
  • 有用的異常方法

    異常及其所有子類均未提供任何特定方法,并且所有方法均在基類Throwable中定義。 創(chuàng)建異常類是為了指定不同類型的異常情況,以便我們可以輕松識別根本原因并根據異常類型進行處理。 Throwable類實現Serializable接口以實現互操作性。

    Throwable類的一些有用方法是:

  • public String getMessage() –此方法返回Throwable消息字符串,并且可以通過其構造函數創(chuàng)建異常時提供該消息。
  • public String getLocalizedMessage() –提供此方法,以便子類可以重寫它以向調用程序提供特定于語言環(huán)境的消息。 此方法的可拋出類實現僅使用getMessage()方法即可返回異常消息。
  • 公共同步Throwable getCause() –此方法返回異常的原因,或者返回null id,原因未知。
  • public String toString() –此方法以String格式返回有關Throwable的信息,返回的String包含Throwable類的名稱和本地化消息。
  • public void printStackTrace() –此方法將堆棧跟蹤信息打印到標準錯誤流,此方法已重載,我們可以傳遞PrintStream或PrintWriter作為參數,以將堆棧跟蹤信息寫入文件或流。
  • Java 7自動資源管理和捕獲塊改進

    如果您在單個try塊中捕獲了很多異常,則您會注意到catch塊代碼看起來非常丑陋,并且主要由用于記錄錯誤的冗余代碼組成,請記住,Java 7的功能之一是改進了catch塊,我們可以在單個catch塊中捕獲多個異常。 具有此功能的catch塊如下所示:

    catch(IOException | SQLException | Exception ex){logger.error(ex);throw new MyException(ex.getMessage()); }

    存在一些約束,例如異常對象是最終對象,我們無法在catch塊內對其進行修改,請在Java 7 Catch Block Improvements上閱讀完整的分析。

    在大多數情況下,我們使用finally塊只是為了關閉資源,有時我們忘記關閉它們并在資源耗盡時獲取運行時異常。 這些異常很難調試,我們可能需要調查使用該類型資源的每個位置,以確保我們將其關閉。 因此,java 7的改進之一是try-with-resources,我們可以在try語句本身中創(chuàng)建資源,并在try-catch塊內使用它。 當執(zhí)行從try-catch塊執(zhí)行時,運行時環(huán)境會自動關閉這些資源。 具有這種改進的try-catch塊示例為:

    try (MyResource mr = new MyResource()) {System.out.println("MyResource created in try-with-resources");} catch (Exception e) {e.printStackTrace();}

    在Java 7自動資源管理中閱讀有關此功能的詳細說明。

    創(chuàng)建自定義異常類

    Java提供了許多異常類供我們使用,但是有時我們可能需要創(chuàng)建自己的自定義異常類,以通過適當的消息以及我們要引入以進行跟蹤的任何自定義字段(例如錯誤代碼)來通知調用方有關特定類型的異常的信息。 。 例如,假設我們編寫了一種僅處理文本文件的方法,因此當其他類型的文件作為輸入發(fā)送時,我們可以為調用者提供適當的錯誤代碼。

    這是自定義異常類的示例,并顯示了其用法。

    MyException.java

    package com.journaldev.exceptions;public class MyException extends Exception {private static final long serialVersionUID = 4664456874499611218L;private String errorCode="Unknown_Exception";public MyException(String message, String errorCode){super(message);this.errorCode=errorCode;}public String getErrorCode(){return this.errorCode;}}

    CustomExceptionExample.java

    package com.journaldev.exceptions;import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream;public class CustomExceptionExample {public static void main(String[] args) throws MyException {try {processFile("file.txt");} catch (MyException e) {processErrorCodes(e);}}private static void processErrorCodes(MyException e) throws MyException {switch(e.getErrorCode()){case "BAD_FILE_TYPE":System.out.println("Bad File Type, notify user");throw e;case "FILE_NOT_FOUND_EXCEPTION":System.out.println("File Not Found, notify user");throw e;case "FILE_CLOSE_EXCEPTION":System.out.println("File Close failed, just log it.");break;default:System.out.println("Unknown exception occured, lets log it for further debugging."+e.getMessage());e.printStackTrace();}}private static void processFile(String file) throws MyException { InputStream fis = null;try {fis = new FileInputStream(file);} catch (FileNotFoundException e) {throw new MyException(e.getMessage(),"FILE_NOT_FOUND_EXCEPTION");}finally{try {if(fis !=null)fis.close();} catch (IOException e) {throw new MyException(e.getMessage(),"FILE_CLOSE_EXCEPTION");}}}}

    請注意,我們可以有一個單獨的方法來處理從不同方法中獲取的不同類型的錯誤代碼,其中一些被消耗掉是因為我們可能不想為此通知用戶,或者其中一些我們將返回以通知用戶有關錯誤代碼。問題。

    在這里,我擴展了Exception,以便每當產生此異常時,都必須在方法中對其進行處理或將其返回給調用程序,如果我們擴展RuntimeException,則無需在throws子句中指定它。 這是一個設計決策,但是我始終喜歡檢查異常,因為我知道調用任何方法并采取適當的措施來處理它們時可以得到哪些異常。

    異常處理最佳實踐

  • 使用特定的異常 -異常層次結構的基類沒有提供任何有用的信息,這就是Java具有這么多異常類的原因,例如IOException以及其他子類,如FileNotFoundException,EOFException等。我們應該始終拋出并捕獲特定的異常類,因此該調用者將輕松知道異常的根本原因并進行處理。 這使調試變得容易,并幫助客戶端應用程序適當地處理異常。
  • 提早或失敗 -我們應盡早提起異常。 考慮上面的processFile()方法,如果將null參數傳遞給此方法,則會得到以下異常。 Exception in thread "main" java.lang.NullPointerExceptionat java.io.FileInputStream.<init>(FileInputStream.java:134)at java.io.FileInputStream.<init>(FileInputStream.java:97)at com.journaldev.exceptions.CustomExceptionExample.processFile(CustomExceptionExample.java:42)at com.journaldev.exceptions.CustomExceptionExample.main(CustomExceptionExample.java:12)

    在調試時,我們將必須仔細查看堆棧跟蹤,以識別異常的實際位置。 如果我們更改實現邏輯以如下所述檢查這些異常;

    private static void processFile(String file) throws MyException {if(file == null) throw new MyException("File name can't be null", "NULL_FILE_NAME"); //further processing }

    然后,異常堆棧跟蹤將如下所示,以清晰的消息清楚地顯示異常發(fā)生的位置。

    com.journaldev.exceptions.MyException: File name can't be nullat com.journaldev.exceptions.CustomExceptionExample.processFile(CustomExceptionExample.java:37)at com.journaldev.exceptions.CustomExceptionExample.main(CustomExceptionExample.java:12)
  • 延遲捕獲 –由于Java強制處理已檢查的異常或在方法簽名中聲明它,因此有時開發(fā)人員傾向于捕獲異常并記錄錯誤。 但是這種做法是有害的,因為調用程序不會收到有關該異常的任何通知。 僅當我們可以適當地處理異常時,才應捕獲異常。 例如,在上述方法中,我將異常拋出給調用方方法以進行處理。 可能希望以不同方式處理異常的其他應用程序可以使用相同的方法。 在實現任何功能時,我們應始終將異常拋出給調用者,并讓他們決定如何處理它。
  • 關閉資源 –由于異常會中斷程序的處理,因此我們應在finally塊中關閉所有資源,或使用Java 7 try-with-resources增強功能讓Java運行時為您關閉它。
  • 記錄異常 –我們應始終記錄異常消息,并在拋出異常時提供清晰的消息,以便調用者可以輕松知道發(fā)生異常的原因。 我們應該始終避免空的catch塊,它只??會消耗異常,并且不會為調試提供任何有意義的異常細節(jié)。
  • 用于多個異常的單個catch塊 –大多數時候,我們記錄異常詳細信息并向用戶提供消息,在這種情況下,我們應該使用java 7功能在單個catch塊中處理多個異常。 這種方法將減少我們的代碼大小,并且看起來也會更干凈。
  • 使用自定義異常 –最好在設計時定義異常處理策略,而不是拋出并捕獲多個異常,我們可以使用錯誤代碼創(chuàng)建自定義異常,并且調用程序可以處理這些錯誤代碼。 創(chuàng)建實用程序方法來處理不同的錯誤代碼并使用它也是一個好主意。
  • 命名約定和打包 –創(chuàng)建自定義異常時,請確保它以Exception結尾,以便從名稱本身就可以清楚看出它是一個異常。 還要確保像在JDK中一樣打包它們,例如IOException是所有IO操作的基本異常。
  • 明智地使用異常 –異常代價高昂,有時甚至根本不需要引發(fā)異常,我們可以向調用者程序返回一個布爾變量,以指示操作是否成功。 如果操作是可選的,并且您不希望程序因失敗而卡住,則這很有用。 例如,在從第三方Web服務更新數據庫中的股票報價時,如果連接失敗,我們可能希望避免引發(fā)異常。
  • 記錄拋出的異常 –使用javadoc @throws可以清楚地指定方法拋出的異常,這在為其他應用程序提供使用接口時非常有用。
  • 這就是Java中異常處理的全部,希望您喜歡它并從中學到一些東西。

    參考: 開發(fā)者食譜博客上的JCG合作伙伴 Pankaj Kumar的Java異常處理教程(帶有示例和最佳實踐) 。

    翻譯自: https://www.javacodegeeks.com/2013/07/java-exception-handling-tutorial-with-examples-and-best-practices.html

    總結

    以上是生活随笔為你收集整理的Java异常处理教程(包含示例和最佳实践)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。