位置:首頁 > Java技術 > Java基礎教程 > Java異常處理

Java異常處理

異常是一個問題的程序的執行期間產生了。異常可能會發生許多不同的原因,包括以下內容:

  • 用戶輸入無效數據。

  • 需要打開的文件不存在。

  • 網絡連接已丟失通信的中間或JVM已經耗儘內存。

有些例外的是由用戶錯誤,其他人造成的程序員的錯誤,和其他人的失敗以某種方式物理資源。

要了解在Java中如何異常處理工作,需要了解三類異常:

  • 檢查異常: 經過檢查的異常是一個例外,通常是用戶錯誤或不能由程序員不可預見的問題。例如,如果一個文件被打開,但該文件無法找到,則會出現異常。這些例外並不能簡單地在編譯時被忽略。

  • 運行時異常: 運行時異常是發生,大概本來是可以避免程序員異常。而不是已檢查異常,運行時異常是在編譯時被忽略。

  • 錯誤: 這些都不例外可言,但所出現超出用戶或程序員的控製問題。錯誤通常忽略了你的代碼,因為你可以很少做任何有關錯誤。例如,如果發生堆棧溢出時,會產生一個錯誤。他們還忽略了在編譯的時候。

異常層次結構:

所有異常類是java.lang.Exception類的子類型。異常類是的Throwable類的子類。以外的異常類有另一個小類稱為錯誤這是從Throwable的類中派生。

錯誤,一般都不會被困形成的Java程序。這些情況通常發生在出現嚴重故障,這不是由java程序處理。產生錯誤指示運行時環境中產生錯誤。例如:JVM是內存不足。通常的程序不能從錯誤中恢複。

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

Java Exceptions

下麵是最常見的選中和未選中列表 Java內置異常.

異常的方法:

以下是在Throwable類中提供重要的方法列表。

SN 方法及描述
1 public String getMessage()
返回有關已發生的異常的詳細消息。此消息在Throwable的構造函數中初始化。
2 public Throwable getCause()
返回異常由一個Throwable對象所代表的原因。
3 public String toString()
返回類連接在一起的getMessage()結果的名稱。
4 public void printStackTrace()
打印toString()結果以及堆棧跟蹤到System.err,錯誤輸出流的結果。
5 public StackTraceElement [] getStackTrace()
返回包含在堆棧跟蹤每一個元素的數組。索引為0的元素表示的調用堆棧的頂部,並在陣列中的最後一個元素表示的方法在調用堆棧的底部。
6 public Throwable fillInStackTrace()
填補了這個Throwable對象的堆棧跟蹤與當前的堆棧跟蹤,增加在堆棧跟蹤以前的任何信息。

捕獲異常:

一種捕獲的方法是使用try和catch關鍵字的組合異常。try/ catch塊放在圍繞之中,可能產生異常的代碼。try/catch塊中的代碼被稱為受保護的代碼,以及語法使用try/catch語句如下所示:

try
{
   //Protected code
}catch(ExceptionName e1)
{
   //Catch block
}

catch語句涉及聲明異常的正在試圖捕捉類型。如果受保護的代碼發生異常,catch塊(或塊)後麵的試一下檢查。如果發生異常的類型列在catch塊,異常被傳遞到catch塊多作為一個參數被傳遞到方法參數。

例子:

下麵是一個數組並有2個元素聲明。然後代碼試圖訪問它拋出一個異常數組的第三個元素。

// File Name : 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

多個catch塊:

一個try塊後麵可以跟多個catch塊。多個catch代碼塊語法如下所示:

try
{
   //Protected code
}catch(ExceptionType1 e1)
{
   //Catch block
}catch(ExceptionType2 e2)
{
   //Catch block
}catch(ExceptionType3 e3)
{
   //Catch block
}

前麵的語句演示3個catch塊,但可以有任意數量的其中的一個try後。如果受保護的代碼發生異常,該異常被拋出到列表中的第一個catch塊。如果拋出的異常的數據類型相匹配ExceptionType1,它就會被捕獲那裡。如果不是,則該異常傳遞到第二catch語句. 這種情況持續下去,直到異常要麼被捕獲或下落通過全部捕獲,在這種情況下,目前的方法停止執行並拋出異常下落到以前的方法調用堆棧。

例子:

下麵是代碼段展示了如何使用多個try/catch語句。

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

throws/throw 關鍵字:

如果一個方法不處理未處理異常,該方法必須使用throw關鍵字聲明它。在拋出的關鍵字出現在方法簽名的結束。

可以拋出一個異常,或者是一個新實例化剛剛捕獲的異常,使用throw關鍵字。試著去了解不同的拋出異常和throw關鍵字。

下麵的方法聲明它會拋出一個RemoteException:

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

一個方法可以聲明它拋出多個異常,在這種情況下,異常都是在以逗號分隔的列表中聲明。例如,下麵的方法聲明它會拋出一個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塊的結尾並具有以下語法:

try
{
   //Protected code
}catch(ExceptionType1 e1)
{
   //Catch block
}catch(ExceptionType2 e2)
{
   //Catch block
}catch(ExceptionType3 e3)
{
   //Catch block
}finally
{
   //The finally block always executes.
}

例子:

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語句。

  • 它不是強製性的有finally子句時,總會有一個try / catch塊存在。

  • try塊中不能出現冇有任何catch子句或finally子句。

  • 任何代碼不能出現在 try, catch, finally 塊之間。

聲明自己的異常:

可以在Java中創建自己的異常。編寫自己的異常類時請注意以下幾點:

  • 所有的異常必須是Throwable的子類。

  • 如果想寫一個檢查異常是處理自動執行或聲明規則,需要擴展Exception類。

  • 如果想編寫一個運行時異常,則需要擴展RuntimeException類。

我們可以定義如下自己的異常處理類:

class MyException extends Exception{
}

隻需要擴展Exception類來創建自己的異常類。這些被認為是已檢查異常。下麵InsufficientFundsException類是擴展了Exception類,使其成為檢查的異常用戶定義的異常。一個異常類是像任何其他類,包含有用的字段和方法。

例子:

// File Name InsufficientFundsException.java
import java.io.*;

public class InsufficientFundsException extends Exception
{
   private double amount;
   public InsufficientFundsException(double amount)
   {
      this.amount = amount;
   } 
   public double getAmount()
   {
      return amount;
   }
}

為了證明我們的使用用戶定義的異常,下麵的CheckingAccount類包含一個withdraw() 方法拋出一個InsufficientFundsException。 

// File Name CheckingAccount.java
import java.io.*;

public class CheckingAccount
{
   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程序演示調用deposit()和withdraw() 方法。

// File Name BankDemo.java
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("
Withdrawing $100...");
         c.withdraw(100.00);
         System.out.println("
Withdrawing $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 異常: - 這些是完全或邏輯拋出由JVM異常/錯誤。例如:NullPointerException異常,ArrayIndexOutOfBoundsException異常,拋出ClassCastException,

  • 編程異常: - 這些異常是由應用程序或API編程實例明確地拋出,如:IllegalArgumentException, IllegalStateException.