溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java異常處理之try...catch...finally的示例分析

發(fā)布時間:2021-08-19 14:10:10 來源:億速云 閱讀:165 作者:小新 欄目:編程語言

這篇文章主要介紹Java異常處理之try...catch...finally的示例分析,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

一.java繼承體系

Java語言為異常處理提供了豐富的異常類,這些類之間有嚴格的繼承關(guān)系。如圖:

Java異常處理之try...catch...finally的示例分析

從圖中我們可以看出,所有的類都是繼承于Throwable這個父類,java將所有的非正常情況分為兩種:Error(錯誤)和Exception(異常),Error錯誤一般是于虛擬機相關(guān)的問題,如系統(tǒng)崩潰、虛擬機錯誤、動態(tài)鏈接失敗等,這種錯誤是無法恢復或不可能捕獲的,而我們能處理的是Exception類下的錯誤。Exception則分為兩大類,RuntimeException(運行時異常)和其他異常(Checked異常),其他異常(Checked異常)是各種形式的編譯錯誤,是我們必須顯示處理才可以通過變異的;而運行時錯誤顧名思義就是程序已經(jīng)通過了編譯,在運行時出現(xiàn)的錯誤,若是對這些異常置之不理會導致程序停止運行、占用資源無法釋放甚至導致系統(tǒng)崩潰。

二.java異常處理機制及實現(xiàn)方法

1.主要依賴于try、catch、finally、throw和throws這五個關(guān)鍵字。(throw和throws本篇不涉及)

2.try…catch…finally處理機制:try關(guān)鍵字后跟一個花括號栝起的代碼塊(即使該代碼塊只有一行也不能省略花括號),簡稱try塊。catch對應(yīng)異常類型和代碼塊,用于表明更改catch塊用于處理該種類型的異常。一個try塊后可以跟多個catch塊。在catch塊后還可以跟一個finally塊,finally塊用于回收在try塊里打開的資源。

這樣講過于抽象,那我們看幾個例子:

e.g.1 try…catch語句塊

//功能:對輸入的兩個數(shù)進行相除運算
public class DivTest {
  public static void main(String[] args) {
    try {
      int a = Integer.parseInt(args[0]);
      int b = Integer.parseInt(args[1]);
      int c = a/b;
      System.out.println("您輸入的兩個數(shù)相除的結(jié)果是:" + c);
    } catch(IndexOutOfBoundsException ie) {
      System.out.println("數(shù)組越界");
    } catch(NumberFormatException ne) {
      System.out.println("數(shù)字格式異常");
    } catch(ArithmeticException ae) {
      System.out.println("算術(shù)異常");
    } catch(Exception e) {
      System.out.println("未知異常");
    } 
  }
}

以上代碼我們看到,對不同的異常情況作了不同的處理:輸入?yún)?shù)不夠會發(fā)生數(shù)組越界異常、輸入?yún)?shù)不是數(shù)字發(fā)生數(shù)字格式異常、若輸入第二個數(shù)是0,則發(fā)生除0異常,調(diào)用算術(shù)異常進行處理、出現(xiàn)其他異常時那么該異常對象必定是Exception類或其子類的實例,java調(diào)用Exception類對其進行處理,前三種異常類均是RuntimeException的子類。在使用try…catch語句塊時需要知道或注意以下幾點:

1) 處理過程:代碼在執(zhí)行的時候,進入try塊,若是在try塊中出現(xiàn)了異常,系統(tǒng)會自動生成一個一場對象,該對象被提交給java運行時環(huán)境,這就是異常的拋出;在java運行時環(huán)境收到異常對象時則把該對象交給catch塊處理,這個過程叫做異常的捕獲;若找到相應(yīng)的catch塊就執(zhí)行catch塊中的代碼,若沒有找到,則運行時環(huán)境終止,程序也退出。

2) 執(zhí)行一次try塊只執(zhí)行一個catch塊

3) 有多個catch塊并有繼承關(guān)系的情況下必須先寫子類后寫父類(即先捕獲小異常再捕獲大異常),若寫反在編譯時就會報錯

4) Java7提供的多異常捕獲:在Java7之前,每一個catch塊只能捕獲一種異常,但從java7開始,一個catch塊可以捕獲多種類型的異常。在使用多異常捕獲應(yīng)注意兩點:

  • (1) 多種異常之間用豎線( | )隔開 

  • (2) 多種異常對象被final隱式修飾,因此程序不能對其重新賦值

以下代碼是多異常捕獲的例子:

e.g.2

//多異常捕獲
public class MultiExceptionTest {
  public static void main(String[] args) {
    try {
      int a = Integer.parseInt(args[0]);
      int b = Integer.parseInt(args[1]);
      int c = a/b;
      System.out.println("您輸入的兩個數(shù)相除的結(jié)果是:" + c);
    } catch(IndexOutOfBoundsException|NumberFormatException|
    ArithmeticException ie) {
      System.out.println("數(shù)組越界或數(shù)字格式異?;蛩阈g(shù)異常");
      ie = new ArithmeticExcrption("test");  //①
    } catch(Exception e) {
      System.out.println("未知異常");
      e = new RuntimeException("test");  //②
    } 
  }
}

可以看出,以上代碼中,①號代碼是錯誤的,因為ie是被final隱式修飾的對象,②號代碼是正確的

3. 使用finally回收資源:有些時候我們在try塊中打開了一些物理資源(例如數(shù)據(jù)庫鏈接、網(wǎng)絡(luò)連接和磁盤文件等),這些資源都應(yīng)進行顯示回收。有人說java不是有垃圾回收機制嗎?java的垃圾回收機制是自動回收堆內(nèi)存中對象所占用的內(nèi)存,而物理資源是不會自動回收的。

finally重點學習以下幾點:

  • 1) 執(zhí)行過程以及引入finally的原因:finally最后執(zhí)行并且最后執(zhí)行,物理資源回收放在finally塊中的原因就是finally塊一定會被執(zhí)行。相反,若是放在try塊中,在執(zhí)行之前就出現(xiàn)異常則跳轉(zhuǎn)至catch塊中,則回收資源的代碼不會被執(zhí)行;同樣的,若是放在catch塊中,若不發(fā)生異常,那么catch塊就不會被執(zhí)行

  • 2) 若是在catch快中有return語句,則先執(zhí)行完finally中的程序后再回到catch塊中并執(zhí)行return語句

  • 3) 若是在finally中有return語句,那么try塊和catch塊中的return語句都會失效,不會被執(zhí)行

  • 4) 若在catch塊中強制退出虛擬機,如使用System.exit(1)語句,則會直接退出程序,finally也不會得到執(zhí)行

e.g.3

//該類功能:打開a.txt文件,在finally塊中對資源進行回收
/* 對代碼中一些方法的解釋:
 * 所有異常都包含以下幾種訪問異常信息的常用方法:
 * getMessage():返回該異常的詳細描述字符串
 * printStackTrace():將該異常的跟蹤棧信息輸出到標準錯誤輸出
 * printStaceTrace(PrintStack s):將該異常的跟蹤棧信息到執(zhí)行輸出流
 * getStackTrace():返回該異常的跟蹤棧信息
 **/
public class FinallyTest {
  public static void main(String[] args) {
    FileInputStream fis = null;
    try {
      fis = new FileInputStream("a.txt");
    }catch(IOException ioe) {
      System.out.println(ioe.getMessage());
      return;      //①
      System.exit(1);  //②
    }finally {
      if(fis != null) {
        try{
          fis.close();
        }catch(IOException ioe) {
          ioe.printStackTrace();
        }
      }
      System.out.println("執(zhí)行finally塊里的資源回收!");
    }
  }
}

注釋掉②號代碼運行以上程序,我們看到的結(jié)果是:

a.txt (系統(tǒng)找不到該文件。)
程序已經(jīng)執(zhí)行了finally里的資源回收!

注釋掉①號代碼運行以上程序,我們看到的結(jié)果是:

a.txt (系統(tǒng)找不到該文件。)

4. 嵌套

例如e.g.3代碼所示,finally塊中還嵌套了一個try…catch語句塊,這種在try塊、catch塊或finally塊中包含完整的異常處理流程的情形被稱為異常的嵌套。一般對嵌套深度沒有限制,但是層次太深的嵌套會降低可讀性。

5.Java7的自動關(guān)閉資源的try語句:

在java7之前,我們必須像e.g.3中的代碼一樣手動關(guān)閉文件,回收資源。在Java7中增強了try語句的功能,它允許在try關(guān)鍵字后緊跟一對圓括號,圓括號可以聲明、初始化一個或多個資源,此處的資源指的是那些必須在程序結(jié)束時顯示關(guān)閉的資源,try語句在該語句結(jié)束時自動關(guān)閉這些資源。這些資源實現(xiàn)類必須實現(xiàn)AutoCloseable或Closeable接口,實現(xiàn)這兩個接口就必須實現(xiàn)close()方法。

注:Closeable是AutoCloseable接口的子接口,Closeable接口里的close()方法聲明拋出了IOException,因此它的實現(xiàn)類在實現(xiàn)close()方法時只能聲明拋出IOException或其子類;AutoCloseable接口里的close()方法聲明拋出了Exception,因此它的實現(xiàn)類在實現(xiàn)close()方法時能拋出任何異常。Java7幾乎把所有的“資源類”(包括文件IO的各種類、JDBC編程的Connection、Statement等接口)進行了改寫,改寫后的資源類都實現(xiàn)了AutoCloseable或Closeable接口

e.g.4

//使用自動回收資源的try語句
public class AutoCloseTest {
  public static void main(String[] args) throws IOException {
    try(
    //聲明、初始化兩個可關(guān)閉的資源,try語句會自動關(guān)閉這兩個資源
    BufferedReader br = new BufferedReader(
    new FileReader("AutoCloseTest.java"));
    PrintStream ps = new PrintStream(
    new FileOutputStream("a.txt"))) {
      //使用兩個資源
      System.out.println(br.readLine());
      ps.println("自動關(guān)閉資源的try語句")
    }
  }
}

以上是“Java異常處理之try...catch...finally的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI