Java異常處理

一、概述

        如果一個人生病了,我們就要對其診斷,然後對症下藥,否則任其病不斷發展下去或是多種病同時存在,這個人就會變得痛苦,不能正常工作。同樣,java是在網絡中運行的,爲了保證運行安全,網絡能正常的運轉,同樣需要找出程序運行時的錯誤,並能夠及時有效的進行處理,則java引出了異常。所謂異常既是不同於正常的,那麼我們也可以稱其爲例外。

二、異常框架

       異常處理在程序設計時非常重要,是程序設計的一個難點,在我們學習C++時,同一個異常或者錯誤如果多個地方出現,那麼我們必須每個地方都要做相同處理,感覺相當麻煩。Java語言設計時就考慮這個問題,提出異常處理框架,所有的異常都可以用一個類型來表示,不同類型的異常對應不同的子類異常,定義了異常處理規範。在1.4版本以後增加了異常鏈機制,從而便於跟蹤異常。

Throwable是類庫java.lang包中的一個類,它派生了兩個子類:Error和Exception。

Throwable是可被拋出的,只要任何繼承它的類都可以拋出。

1、Error:系統內部錯誤,是程序無法處理的錯誤。

       它表示運行應用程序時較嚴重的問題。大多數錯誤與代碼編寫執行者的操作無關,這些錯誤是不可查的,他們在應用程序的控制和處理能力之外,而表示代碼運行時JVM出現的問題。例如:java虛擬機運行錯誤、當JVM不再有繼續執行操作所需要的內存資源時,將出現OutOfMemoryError。這些異常發生錯誤時,Java虛擬機一般會選擇終止線程。

2、Exception:程序本身可以處理的異常。

Exception包括:運行時異常錯誤和非運行時異常(編譯異常)。

(1)運行時異常(可查異常):Java編譯器不檢查它,也就是說,當程序中可能出現這類異常,即使沒有用try-catch語句捕獲它,也沒有用throws子句聲明拋出它,也會編譯通過。包括RuntimeException及其子類。這些異常一般是程序邏輯錯誤引起的,程序應該從邏輯角度儘可能避免這類異常的發生。

(2)非運行時異常(不可查異常): Java編譯器會檢查它,也就是說,當程序中可能出現這類異常,要用try-catch語句捕獲它,或用throws子句聲明拋出它,否則編譯不通過。包括除RuntimeException以外的其它類。

補充:可查異常即編譯器要求必須處置的異常:不可查異常即編譯器不要求強制處置的異常,它還包括錯誤(Error)。

Exception同其他類一樣,有自己的屬性和方法,瞭解它有利於我們更好的用戶自定義異常類。

它的兩個構造函數是

Public Exception();

Public Exception(String s);

它的常用方法是

Public StringtoString()//這個方法用來給出詳細的錯誤信息

Public voidprintStackTrace()//打印出當前異常對象的堆棧使用軌跡,即程序先後執行了那些對象或類的方法,才使得運行過程中產生了這個異常對象。

小結:錯誤和異常的最主要區別:異常可被程序本身處理,錯誤不可以。

三、定義異常

1、 系統定義的運行異常:是系統事先定義好幷包裝在java類庫中的。它通常對應着系統運行錯誤,這種錯誤很可能導致操作系統錯誤,甚至整個系統的癱瘓,所以要定義特別類來進行處理。常見的系統定義異常可參見http://soft.chinabyte.com/database/491/12129991.shtml這個網址,這位博主整理的不錯。

2、 用戶自定義的異常:是編程人員根據程序的特殊邏輯在用戶程序裏自己創建用戶自定義的異常類和異常對象。這種用戶自定義異常主要用來處理用戶程序中特定的邏輯運行錯誤。

下面定義的是隊列類的一個出隊方法,這個僅是代碼一部分:

class Queue
{
	int dequeue ()  //減隊操作,若隊列不空,則從隊列頭部取出一個數據
	{
	    int data ;
		if(!isEmpty()){
		    data = First.getData();
			First=First.getNext();
			return;
		}else{
		     return -1
		}
	}

}

        在這個方法裏,如果隊列已經爲空,則此方法給出一個數據“-1”表示出隊的操作失敗,這樣處理的壞處是對壘不能保存“-1”這個數據,同時還要求其他調用dequeue的方法瞭解這個異常的約定,顯然對程序的調試和運行都不方便,爲解決這個問題,可以定義一個程序異常EmptyQueueException,專門處理“從空隊列中出隊”的邏輯錯誤。

class EmptyQueueException extends Exception     //用戶自定義的系統類的子類
{
	Queue queue;
    public EmptyQueueException(Queue q){
	    super("隊列已空!");
		queue = q;
	}

	public String toString(){         //重載父類的方法,給出詳細的錯誤信息       
	    return ("隊列" + queue.toString() + "已經爲空,執行出隊操作引發異常!");
	}
}

四、拋出異常

Java程序在運行時如果引發了一個可以識別的錯誤,就會產生一個與該錯誤對應的異常類對象,這個過程被稱爲異常的拋出。

1、 系統自動拋出的異常:系統定義的異常都可以由系統自動拋出。如:以零爲除數時出現的算數異常。

2、 語句拋出的異常

用戶自定義的異常不能依靠系統拋出,必須藉助throw語句。並應該拋出這個異常類的新對象如果拋出的是Exception異常類型,則該方法被聲明爲拋出所有的異常。多個異常可使用逗號分割。throws語句的語法格式爲:

methodname throws Exception1,Exception2,..,ExceptionN
 {   …
    Thrownew 異常類名;
    …
 } ;

以下代碼展示我們怎樣拋出上面的queue()方法可能拋出EmptyQueueExpection異常對象

class Queue
{
	int dequeue () throws EmptyQueneException  //減隊操作,若隊列不空,則從隊列頭部取出一個數據
	{
	    int data ;
		if(!isEmpty()){
		    data = First.getData();
			First=First.getNext();
			return;
		}else{
		     throw( new EmptyQueueException(this));
		}
	}

}

拋出異常注意事項:

1、 重寫方法需要拋出與原方法所拋出異常類型一致或者不拋出異常;

2、 必須聲明方法可拋出的任何可查異常(checked exception)。即如果一個方法可能出現受可查異常,要麼用try-catch語句捕獲,要麼用throws子句聲明將它拋出,否則會導致編譯錯誤

3、 在編程中不能在main中拋出異常,要進行處理在main方法中

五、異常處理

當我們拋出異常的時候,要進行異常的處理。異常處理主要包括捕捉異常、程序流程的跳轉和異常處理語句塊的定義。

異常處理的格式:

Try{
   //可能會發生異常的程序代碼
}
Catch{
  //捕獲並處理try拋出的異常類型,可以有多個catch語句
}
Finally{
  //對程序的狀態做統一的處理
}

針對上面的例子,做異常處理,代碼如下:

public class test
{
	public static void main(String args[]){
	   Queue queue = new Queue();

	   for ( ing i=1;i<8;i++ )
	   {
		   queue.enqueue(i);   //調用Queue的入隊函數
		   System.out.println(queue.visitAllNode()); //顯示隊列中的內容
	   }

	   try
	   {
		  while (!queue.isEmpty())   //調用出隊函數
		  {
			  System.out.print(queue.dequeue()+"出隊");
              System.out.print("隊列中還有" + queue.visitAllNode());
		  }
	   }
	   catch ( EmptyQueueException eqe)
	   {
		   System.out.println(eqe.toString());
	   }
	}
}

       針對多異常的處理,是定義若干個塊來實現的,每個塊用來接收和處理一種特定的異常對象,並且異常類型小的放前,大的放後,經常出錯的放前,不經常出錯的放後面,因爲catch是按先後順序排列的。如果所有的catch塊與不能與當前的異常對象匹配,則說明當前方法不能處理這個異常對象,程序流將返回到調用該方法的上層方法,如果這個上層方法中定義了與所產生的異常對象相匹配的catch塊,流程就轉到這個catch中;否則繼續回溯,如下圖展示情況:

  

異常處理的原則:

1、避免過大的try塊,不要把不會出現異常的代碼放到try塊裏面,儘量保持一個try塊對應一個或多個異常。

2、細化異常的類型,不要不管什麼類型的異常都寫成Excetpion。

3、catch塊儘量保持一個塊捕獲一類異常,不要忽略捕獲的異常,捕獲到後要麼處理,要麼轉譯,要麼重新拋出新類型的異常。

4、不要用try...catch參與控制程序流程,異常控制的根本目的是處理程序的非正常情況。

六、總結

         總之,程序執行時經常會出現除零溢出、數組越界等運行錯誤,影響程序的正常執行。錯誤及異常是不可避免的,一個好的應用程序,在滿足用戶要求的各種功能的同時,還應具備能預見程序執行過程中可能產生的各種異常的能力,並能爲異常情況給予恰當處理。Java語言通過面向對象的異常處理機制來解決運行期間的錯誤,可以預防錯誤的程序代碼或系統錯誤所造成的不可預期的結果發生。減少編程人員的工作,增加了程序的靈活性,增加程序的可讀性和健壯性。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章