異常是程序中的一些錯誤,但並非全部的錯誤都是異常,而且錯誤有時候是能夠避免的。java
好比說,你的代碼少了一個分號,那麼運行出來結果是提示是錯誤 java.lang.Error;若是你用System.out.println(11/0),那麼你是由於你用0作了除數,會拋出 java.lang.ArithmeticException 的異常。程序員
異常發生的緣由有不少,一般包含如下幾大類:網絡
這些異常有的是由於用戶錯誤引發,有的是程序錯誤引發的,還有其它一些是由於物理錯誤引發的。-this
要理解Java異常處理是如何工做的,你須要掌握如下三種類型的異常:spa
全部的異常類是從 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 關鍵字來聲明。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 關鍵字用來建立在 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
注意下面事項:
在 Java 中你能夠自定義異常。編寫本身的異常類時須要記住下面的幾點。
只繼承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中定義了兩種類型的異常和錯誤。