Java異常處理
異常是一個問題的程序的執行期間產生了。異常可能會發生許多不同的原因,包括以下內容:
-
用戶輸入無效數據。
-
需要打開的文件不存在。
-
網絡連接已丟失通信的中間或JVM已經耗儘內存。
有些例外的是由用戶錯誤,其他人造成的程序員的錯誤,和其他人的失敗以某種方式物理資源。
要了解在Java中如何異常處理工作,需要了解三類異常:
-
檢查異常: 經過檢查的異常是一個例外,通常是用戶錯誤或不能由程序員不可預見的問題。例如,如果一個文件被打開,但該文件無法找到,則會出現異常。這些例外並不能簡單地在編譯時被忽略。
-
運行時異常: 運行時異常是發生,大概本來是可以避免程序員異常。而不是已檢查異常,運行時異常是在編譯時被忽略。
-
錯誤: 這些都不例外可言,但所出現超出用戶或程序員的控製問題。錯誤通常忽略了你的代碼,因為你可以很少做任何有關錯誤。例如,如果發生堆棧溢出時,會產生一個錯誤。他們還忽略了在編譯的時候。
異常層次結構:
所有異常類是java.lang.Exception類的子類型。異常類是的Throwable類的子類。以外的異常類有另一個小類稱為錯誤這是從Throwable的類中派生。
錯誤,一般都不會被困形成的Java程序。這些情況通常發生在出現嚴重故障,這不是由java程序處理。產生錯誤指示運行時環境中產生錯誤。例如:JVM是內存不足。通常的程序不能從錯誤中恢複。
Exception類主要有兩個子類:IOException類和RuntimeException異常類。
下麵是最常見的選中和未選中列表 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.