1. 程式人生 > >Java中try-catch-finally語句塊的應用

Java中try-catch-finally語句塊的應用

一、異常處理及catch的順序

  catch塊跟在try語句後面,它可以是一個或多個;catch塊有一個引數,該引數是某種異常類的物件;多重catch語句中,異常型別必須子類在前父類在後;try語句塊不可以獨立存在,必須與catch或者finally塊共存

語法

try{
  //一些會丟擲異常的方法
}catch(Exception e){
  //處理該異常的程式碼塊
}catch(Exception2 e){
  //處理Exception2的程式碼塊
}...(n個catch塊)...{
}finally{
  //最終將要執行的一些程式碼
}

示例

  下面的類給出了divider(除數),result(結果),利用try-catch捕獲while迴圈。每次迴圈,divider減一,result=result+100/divider。如果捕獲異常,列印輸出“丟擲異常了!!!”,返回-1;否則返回result

package com.exer.mytest;

public class TryCatchTest{

  public static void main(String[] args){
    TryCatchTest tct = new TryCatchTest();
    int result = tct.test();
    System.out.println("test()方法執行完畢,返回值為:"+result);
  }

public int test(){
  int divider = 10;
  int result = 100;
  try{
    while
(divider > -1){ divider--; result = result + 100/divider; } return result; }catch(Exception e){ e.printStackTrace();//打出丟擲異常的具體資訊 System.out.println("迴圈丟擲異常了!!!"); return -1; } } }

執行結果:

  迴圈丟擲異常了!!!
  test()方法執行完畢,返回值為:-1
  java.lang.ArthmeticException:/by zero
     at com.exer.mytest.TryCatchTest.test(TryCatchTest.java:17)
     at com.exer.mytest.TryCatchTest.main(TryCatchTest.java:7)

public static void main(String[] args){
    TryCatchTest tct = new TryCatchTest();
    int result = tct.test();
    System.out.println("test()方法執行完畢,返回值為:"+result);
    int result2 = tct.test2();
    System.out.println("我想大聲告訴你!test2()方法執行完畢!!");
}

public int test2(){
  int divider = 10;
  int result = 100;
  try{
    while(divider > -1){
      divider--;
      result = result + 100/divider;
    }
    return result;
  }catch(Exception e){
    //e.printStackTrace();//打出丟擲異常的具體資訊
    System.out.println("迴圈丟擲異常了!!!");
    return result = 999;
  }finally{
    System.out.println("這是finally!!哈哈!!");
    System.out.println("我是Result!!我的值是:"+result);
  }
}

執行結果:

  迴圈丟擲異常了!!!
  這是finally!!哈哈!!
  我是Result!我的值是:999
  我想大聲告訴你!test2()方法執行完畢!!

  從以上例子中可以看出,finally塊是在try塊和catch塊執行完成之後,返回到呼叫者之前會執行的。

public static void main(String[] args){
    TryCatchTest tct = new TryCatchTest();
    int result = tct.test3();
    System.out.println("我想大聲告訴你!test3()方法執行完畢!!~返回值為:"+result);
}


public int test3(){
  int divider = 10;
  int result = 100;
  try{
    while(divider > -1){
      divider--;
      result = result + 100/divider;
    }
  }catch(Exception e){
    //e.printStackTrace();//打出丟擲異常的具體資訊
    System.out.println("迴圈丟擲異常了!!!");
  }finally{
    System.out.println("這是finally!!哈哈!!");
    System.out.println("我是Result!!我的值是:"+result);
  }
  System.out.println("我是test3!我執行完了!表想我");
  return 1111;
}

執行結果:

  迴圈丟擲異常了!!!
  這是finally!!哈哈!!
  我是Result!我的值是:381
  我是test3!我執行完了!表想我
  我想大聲告訴你!test3()方法執行完畢!!~返回值為:1111

二、異常丟擲

  Java中的異常丟擲會用到throw和throws。throws宣告將要丟擲何種型別的異常,是一個宣告,throw指將產生的異常丟擲,是一個動作。如果某個方法呼叫到了會丟擲異常的方法,那麼必須新增try-catch語句去嘗試捕獲這種異常,或者新增throws宣告,來將異常丟擲給更上一層的呼叫者去進行處理。

  自定義異常是自己定義的異常型別,但這個自定義異常類必須繼承Java標準異常庫中意思相近的異常型別,或者直接繼承所有異常型別的基類,即Exception型別。

例如

public calss DrunkException extends Exception{

  public DrunkException(){
  }
  public DrunkException(String message){
    super(message);
  }
}

三、異常鏈

  有時候,可以把捕獲的異常包裝成一個新的異常,然後在新的異常裡面新增對原始異常的引用,再把新異常丟擲,就像是鏈式反應一樣。

public class ChainTest(){

  public static void main(String[] args){
    ChainTest ct = new ChainTest();
    try{
      ct.test2();
    }catch(Exception e){
      e.printStackTrace();
    }
  }

  public void test1() throws DrunkException{
    throw new DrunkException("喝酒別開車!");
  }

  public void test2(){
    try{
      test1();
    }catch(DrunkException e){
      RuntimeException newExc = new RuntimeException("司機一滴酒,親人兩行淚~~");
      newExc.initCause(e);
      throw newExc;
    }
  }

}

test2()另一種寫法

```Java
public void test2(){
    try{
      test1();
    }catch(DrunkException e){
      RuntimeException newExc = new RuntimeException(e);
      //newExc.initCause(e);
      throw newExc;
    }
  }

小結:

  1. 處理執行時異常時,採用邏輯去合理規避同時輔助try-catch處理
  2. 在多重catch塊後面,可以加一個catch(Exception)來處理可能會被遺漏的異常
  3. 對於不確定的程式碼,也可以加上try-catch,處理潛在的異常
  4. 儘量去處理異常,切忌只是簡單的呼叫printStackTrace()去列印輸出
  5. 具體如何異常,要根據不同的業務需求和異常型別去決定
  6. 儘量新增finally語句塊去釋放佔用的資源