Java的異常理解

1.什麼是異常

        在Java程序運行時,常常會出現一些非正常的現象,這種情況稱爲錯誤。根據其性質分爲錯誤和異常。Java程序中(無論誰寫的代碼),所有拋出的(throw)的異常都必須從Throwable派生而來。類Throwable有兩個子類:Error和Exception。如下結構圖:

      一般來說,最常見的錯誤有程序進入死循環、內存泄漏等。這種情況下,程序運行時本身無法解決,只能通過其他程序的干預。Java對應的類爲Error類。Error類對象由Java虛擬機生成並拋棄(通常情況下Java程序不對這類異常進行處理)。

    異常是程序執行時遇到的非正常情況或意外。一般比如:代碼或調用的代碼(如共享庫)中有錯誤,操作系統資源不可用,公共語言運行庫遇到意外情況(如無法驗證代碼)等。常見的有數組下標越界、算法溢出(超出數值表達範圍)、 除數爲零、無效參數、內存溢出等。這種情況不像錯誤類那樣,程序運行時本身無法解決,由異常代碼調整程序運行方向,使程序仍可以繼續運行,直到正常結束。

       Java異常對應的類爲Exception類。Exception類對象是Java程序處理或拋棄的對象,它有各種不同的子類分別對應不同的異常類型。Java編譯器要求程序必須捕獲或聲明所有的非運行時異常,但對運行時異常可以不做處理。其中類RuntimeException代表運行時由Java虛擬機生成的異常,原因是編程錯誤。其他則爲非運行時異常,原因是程序碰到了意外情況,如輸入/輸出異常IOException等。

2.異常關鍵字

Java異常處理的關鍵語句有五個:try、catch、throw、throws、finally。其中,try、catch、finally三個語句注意以下問題:

1)try、catch、finally三個語句塊均不能單獨使用,三者可以組成try...catch...finally、try...catch、try...finally三種結構,catch語句可以有一個或多個,finally語句最多一個。

2)try、catch、finally三個代碼塊中變量的作用域爲代碼塊內部,分別獨立而不能相互訪問。如果要在三個塊中都可以訪問,則需要將變量定義到這些塊的外面。

3)若多個catch塊,只會匹配其中一個異常類並執行catch塊裏的代碼,而不會再執行別的catch塊,並且匹配catch語句的順序是由上到下的。

4)執行的返回值會最終被finally中的返回值覆蓋掉如下代碼:

import org.junit.Test;

/**測試捕獲異常的執行順序
 * @author QuLei
 *
 */
public class TestException {
	@Test
	public void test1() {
		int i =test();
		System.out.println(i);
	}
	/**測試try、catch、finally的執行順序以及return的返回值,前
	 * 面的返回值會被finally中的覆蓋掉
	 * @return 
	 */
	@SuppressWarnings("finally")
	public  int test() {
		int i = 1;
		try {
			i = 1+3;
			//i = 1/0;
			System.out.println(i);
			return i;
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			return 1;
		}finally {
			return 2;
		}
	} 
}

5).throw、throws關鍵字的區別。

        throw關鍵在用於方法體內部,用來拋出一個Throwable類型的異常。如果拋出了檢查異常,則還應該在頭部聲明方法可能拋出的異常類型。該方法的調用者也必須檢查異常。如果所有的方法都層層上拋獲取的異常,最終JVM會進行處理,處理也很簡單,就是打印異常消息和對堆棧信息。如果拋出的是Error或RuntimeException,則該方法的調用者可以選則處理該異常。

        throws關鍵字用於方法外部的方法聲明部分,用來聲明方法可能會拋出某些異常。僅當拋出了檢查異常,該方法的調用者才必須處理或重新拋出該異常。

3.異常處理中的問題

1)過於龐大的try塊

          儘可能的設置多個異常拋出點來解決。異常從產生點開始,到被捕獲後終止的全過程中,實際是一個傳值的過程,所以,應根據實際來合理的控制檢測異常個數。catch語句表示會出現某種異常,而且希望能夠處理該異常。所以在catch語句中儘量指定具體的異常類型。

2)異常處理的完整性

   在Java中,如果一個函數被調用可能會向上拋一個異常,那麼,它就必須在該函數的聲明中顯示地註明(採用trhrows關鍵字)。

3)RuntimeException可以捕獲處理,也可以交給虛擬機處理。       

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