java-異常處理

Java 異常處理

異常是程序中的一些錯誤,但並非全部的錯誤都是異常,而且錯誤有時候是能夠避免的。java

好比說,你的代碼少了一個分號,那麼運行出來結果是提示是錯誤 java.lang.Error;若是你用System.out.println(11/0),那麼你是由於你用0作了除數,會拋出 java.lang.ArithmeticException 的異常。程序員

異常發生的緣由有不少,一般包含如下幾大類:網絡

  • 用戶輸入了非法數據。
  • 要打開的文件不存在。
  • 網絡通訊時鏈接中斷,或者JVM內存溢出。

這些異常有的是由於用戶錯誤引發,有的是程序錯誤引發的,還有其它一些是由於物理錯誤引發的。-this

要理解Java異常處理是如何工做的,你須要掌握如下三種類型的異常:spa

  • 檢查性異常:最具表明的檢查性異常是用戶錯誤或問題引發的異常,這是程序員沒法預見的。例如要打開一個不存在文件時,一個異常就發生了,這些異常在編譯時不能被簡單地忽略。
  • 運行時異常: 運行時異常是可能被程序員避免的異常。與檢查性異常相反,運行時異常能夠在編譯時被忽略。
  • 錯誤: 錯誤不是異常,而是脫離程序員控制的問題。錯誤在代碼中一般被忽略。例如,當棧溢出時,一個錯誤就發生了,它們在編譯也檢查不到的。

Exception 類的層次

全部的異常類是從 java.lang.Exception 類繼承的子類。blog

Exception 類是 Throwable 類的子類。除了Exception類外,Throwable還有一個子類Error 。繼承

Java 程序一般不捕獲錯誤。錯誤通常發生在嚴重故障時,它們在Java程序處理的範疇以外。three

Error 用來指示運行時環境發生的錯誤。內存

例如,JVM 內存溢出。通常地,程序不會從錯誤中恢復。ci

異常類有兩個主要的子類:IOException 類和 RuntimeException 類。

在 Java 內置類中(接下來會說明),有大部分經常使用檢查性和非檢查性異常。

 

捕獲異常

使用 try 和 catch 關鍵字能夠捕獲異常。try/catch 代碼塊放在異常可能發生的地方。

try/catch代碼塊中的代碼稱爲保護代碼,使用 try/catch 的語法以下:

Catch 語句包含要捕獲異常類型的聲明。當保護代碼塊中發生一個異常時,try 後面的 catch 塊就會被檢查。

若是發生的異常包含在 catch 塊中,異常會被傳遞到該 catch 塊,這和傳遞一個參數到方法是同樣。

// 文件名 : ExcepTest.java
import java.io.*;
public class ExcepTest{
 
   public static void main(String args[]){
      try{
         int a[] = new int[2];
         System.out.println("Access element three :" + a[3]);
      }catch(ArrayIndexOutOfBoundsException e){
         System.out.println("Exception thrown  :" + e);
      }
      System.out.println("Out of the block");
   }
}

結果:
Exception thrown  :java.lang.ArrayIndexOutOfBoundsException: 3
Out of the block

 

多重捕獲塊

一個 try 代碼塊後面跟隨多個 catch 代碼塊的狀況就叫多重捕獲。

多重捕獲塊的語法以下所示:

try{
   // 程序代碼
}catch(異常類型1 異常的變量名1){
  // 程序代碼
}catch(異常類型2 異常的變量名2){
  // 程序代碼
}catch(異常類型2 異常的變量名2){
  // 程序代碼
}

上面的代碼段包含了 3 個 catch塊。

能夠在 try 語句後面添加任意數量的 catch 塊。

若是保護代碼中發生異常,異常被拋給第一個 catch 塊。

若是拋出異常的數據類型與 ExceptionType1 匹配,它在這裏就會被捕獲。

若是不匹配,它會被傳遞給第二個 catch 塊。

如此,直到異常被捕獲或者經過全部的 catch 塊。

實例

該實例展現了怎麼使用多重 try/catch。

try {
    file = new FileInputStream(fileName);
    x = (byte) file.read();
} catch(FileNotFoundException f) { // Not valid!
    f.printStackTrace();
    return -1;
} catch(IOException i) {
    i.printStackTrace();
    return -1;
}

 

throws/throw 關鍵字:

若是一個方法沒有捕獲到一個檢查性異常,那麼該方法必須使用 throws 關鍵字來聲明。throws 關鍵字放在方法簽名的尾部。

也可使用 throw 關鍵字拋出一個異常,不管它是新實例化的仍是剛捕獲到的。

下面方法的聲明拋出一個 RemoteException 異常:

一個方法能夠聲明拋出多個異常,多個異常之間用逗號隔開。

例如,下面的方法聲明拋出 RemoteException 和 InsufficientFundsException:

import java.io.*;
public class className
{
   public void withdraw(double amount) throws RemoteException,
                              InsufficientFundsException
   {
       // Method implementation
   }
   //Remainder of class definition
}

 

finally關鍵字

finally 關鍵字用來建立在 try 代碼塊後面執行的代碼塊。

不管是否發生異常,finally 代碼塊中的代碼總會被執行。

在 finally 代碼塊中,能夠運行清理類型等收尾善後性質的語句。

finally 代碼塊出如今 catch 代碼塊最後,

public class ExcepTest{
  public static void main(String args[]){
    int a[] = new int[2];
    try{
       System.out.println("Access element three :" + a[3]);
    }catch(ArrayIndexOutOfBoundsException e){
       System.out.println("Exception thrown  :" + e);
    }
    finally{
       a[0] = 6;
       System.out.println("First element value: " +a[0]);
       System.out.println("The finally statement is executed");
    }
  }
}

結果:
Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 3 First element value: 6 The finally statement is executed

注意下面事項:

  • catch 不能獨立於 try 存在。
  • 在 try/catch 後面添加 finally 塊並不是強制性要求的。
  • try 代碼後不能既沒 catch 塊也沒 finally 塊。
  • try, catch, finally 塊之間不能添加任何代碼。

聲明自定義異常

在 Java 中你能夠自定義異常。編寫本身的異常類時須要記住下面的幾點。

  • 全部異常都必須是 Throwable 的子類。
  • 若是但願寫一個檢查性異常類,則須要繼承 Exception 類。
  • 若是你想寫一個運行時異常類,那麼須要繼承 RuntimeException 類。

只繼承Exception 類來建立的異常類是檢查性異常類。

下面的 InsufficientFundsException 類是用戶定義的異常類,它繼承自 Exception。

一個異常類和其它任何類同樣,包含有變量和方法。

實例

如下實例是一個銀行帳戶的模擬,經過銀行卡的號碼完成識別,能夠進行存錢和取錢的操做。

// 文件名InsufficientFundsException.java
import java.io.*;
 
//自定義異常類,繼承Exception類
public class InsufficientFundsException extends Exception
{
  //此處的amount用來儲存當出現異常(取出錢多於餘額時)所缺少的錢
  private double amount;
  public InsufficientFundsException(double amount)
  {
    this.amount = amount;
  } 
  public double getAmount()
  {
    return amount;
  }
}

在下面的 CheckingAccount 類中包含一個 withdraw() 方法拋出一個 InsufficientFundsException 異常。

import java.io.*;
 
//此類模擬銀行帳戶
public class CheckingAccount
{
  //balance爲餘額,number爲卡號
   private double balance;
   private int number;
   public CheckingAccount(int number)
   {
      this.number = number;
   }
  //方法:存錢
   public void deposit(double amount)
   {
      balance += amount;
   }
  //方法:取錢
   public void withdraw(double amount) throws
                              InsufficientFundsException
   {
      if(amount <= balance)
      {
         balance -= amount;
      }
      else
      {
         double needs = amount - balance;
         throw new InsufficientFundsException(needs);
      }
   }
  //方法:返回餘額
   public double getBalance()
   {
      return balance;
   }
  //方法:返回卡號
   public int getNumber()
   {
      return number;
   }
}

下面的 BankDemo 程序示範瞭如何調用 CheckingAccount 類的 deposit() 和 withdraw() 方法。

public class BankDemo
{
   public static void main(String [] args)
   {
      CheckingAccount c = new CheckingAccount(101);
      System.out.println("Depositing $500...");
      c.deposit(500.00);
      try
      {
         System.out.println("\nWithdrawing $100...");
         c.withdraw(100.00);
         System.out.println("\nWithdrawing $600...");
         c.withdraw(600.00);
      }catch(InsufficientFundsException e)
      {
         System.out.println("Sorry, but you are short $"
                                  + e.getAmount());
         e.printStackTrace();
      }
    }
}

編譯上面三個文件,並運行程序 BankDemo,獲得結果以下所示:

Depositing $500...

Withdrawing $100...

Withdrawing $600...
Sorry, but you are short $200.0
InsufficientFundsException
        at CheckingAccount.withdraw(CheckingAccount.java:25)
        at BankDemo.main(BankDemo.java:13)

通用異常

在Java中定義了兩種類型的異常和錯誤。

  • JVM(Java虛擬機) 異常:由 JVM 拋出的異常或錯誤。例如:NullPointerException 類,ArrayIndexOutOfBoundsException 類,ClassCastException 類。
  • 程序級異常:由程序或者API程序拋出的異常。例如 IllegalArgumentException 類,IllegalStateException 類。
相關文章
相關標籤/搜索