Java高級之異常

異常

1 什麼是Java中的異常

           Java中的異常就是Java程序在運行時會出現的一些錯誤,這些錯誤會影響程序正常的指令流程,從而導致程序不能夠繼續運行下去。打個比方,Java中出現的異常就是我們在現實世界中的生病,有的病可以預防,有的病可以治療,有的病依照目前的醫療水平還不能治療。Java異常也是如此,可以避免和處理,也有處理不了的。
        在開發過程中,作爲程序開發者,我們儘量的去避免這些可以避免的異常,儘量去處理這些可以處理的異常。

2 怎麼描述Java異常

        在開發者的世界裏,有一句話特別經典:萬物皆對象。所以說Java中出現的所有異常都會用對象來描述它,這些描述異常的類在Java中有一個超類,即Throwable類,該類定義了描述程序中出現的異常的基本模板。
        Throwable類直接衍生出來的類只有兩個:ErrorException。Error類就是我們之前所說的無法處理的Java異常,一般是Java虛擬機出現的錯誤(如果沒有了解過虛擬機的話,就不要深究該問題,筆者也沒有了解過JVM);Exception纔是我們在寫程序時經常會遇見的Java異常,在編寫程序時,99%遇見的都是該類異常
        Error是我們編寫的程序自身無法處理的異常,Exception是我們程序自身可以處理的異常。

3 Exception的描述

       關於Exception中的分類有不同的看法,不過一般的都認同上圖中的分類:運行時非運行時異常。這兩種分類怎麼理解呢?
        就像他兩的名字中的“運行”兩字,我們都知道Java編寫的源代碼是需要編譯的(將.java文件編譯成.class)文件,然後纔會運行字節碼文件。所以運行時異常就是程序在運行的時候出現的異常,非運行時異常就是在編譯階段出現的異常(比如我們用Myeclipse編寫階段編寫Java代碼時需要處理的異常)。

 4 怎麼處理異常

       處理異常有兩個階段,而且是有先後順序的:拋出異常捕獲異常
        拋出異常就兩個關鍵字:throw和throws,而且兩個關鍵字必須是一起存在的,缺一不可。方法聲明處用throws聲明拋出的是什麼類型的異常,用throw在方法中拋出具體的異常對象(new出來的異常對象)。
        捕獲異常就三個關鍵字:try、catch和finally,其中的組合有規則,只能有一個try和一個finally,catch塊可以有0個或多個。
拋出異常:除數不能爲零的異常
public void testThrow(int a, int b) throws ArithmeticException {
        if(b == 0) throw new ArithmeticException();
	}
捕獲異常:try...catch...finally
public static void main(String[] args) {
		try {
			int count = 5/0;
		} catch (ArithmeticException e) {
			// TODO: handle exception
			System.out.println(e.getMessage());
		} catch(Exception e) {
			System.out.println(e.getMessage());
		} finally {
			System.out.println("方法返回前必須執行的代碼塊");
		}
	}

5 異常應該注意的問題

   異常理解起來並不是很難,關鍵的是異常的細節。一些細節的問題纔是筆試和麪試當中常見的問題。
try不能單獨存在
        try只能和catch或者finally或者catch和finally聯合使用,它不能單獨存在。
        try語句塊是是我們需要監測的代碼,即可能會出現異常的代碼塊。
catch不能單獨存在
       catch只能夠和try語句塊聯合使用,而且可以有多個catch語句塊。
finally語句塊一定會執行嗎
          在一般情況下,finally語句塊是一定會執行的。但是我們要知道也有特殊情況:電腦沒電、程序強制退出、線程死亡等等。
        如果try和catch語句塊沒有return,finally語句塊是一定會執行的。
        如果try和catch語句塊有return,那麼一定會在return之前執行finally語句塊(如果finally語句塊裏也有return,那麼就會在finally語句塊中返回)。
        如果catch語句塊中有拋出異常,那麼與throw同一個代碼塊之後的代碼不會執行(比如try代碼塊、catch代碼塊),但是finally還是會執行。
        大家可以猜猜下面的輸出結果:
package testException;
/**
 * 
 * @author Administrator
 * 測試異常的try、catch、finally的關係
 */
public class TestException1 {
	
	public TestException1() {  
    }  
  
    @SuppressWarnings("finally")
	boolean test1() throws Exception {  
        boolean flag = true;  
        try {  
        	System.out.println("test2的try語句塊");  
        	flag = test2();  
        } catch (Exception e) {  
            System.out.println("test1的catch語句塊");  
            flag = false;  
            throw e;  
        } finally {  
            System.out.println("test1的finally語句塊,方法返回值=" + flag);  
            return flag;  
        }  
    }  
  
    @SuppressWarnings("finally")
	boolean test2() throws Exception {  
        boolean flag = true;  
        try {  
        	flag = test3();  
            if (!flag) {  
                return false;  
            }  
            System.out.println("test2的try語句塊");  
            return flag;  
        } catch (Exception e) {  
            System.out.println("test2的catch語句塊");  
            flag = false;  
            throw e;  
        } finally {  
            System.out.println("test2的finally語句塊,方法返回值=" + flag);  
            return flag;  
        }  
    }  
  
    @SuppressWarnings("finally")
	boolean test3() throws Exception {  
        boolean flag = true;  
        try {
            for (int i = 4; i >= -1; i--) {  
                int c = 10 / i;  
                System.out.println("i=" + i);  
            } 
            System.out.println("test2的try語句塊");  
            return true;  
        } catch (Exception e) {  
            System.out.println("test3的catch語句塊");  
            flag = false;  
            throw e;  
        } finally {  
            System.out.println("test3的finally語句塊,方法返回值=" + flag);  
            return flag;  
        }  
    }  
  
    public static void main(String[] args) {  
        TestException1 testException1 = new TestException1();  
        try {  
            testException1.test1();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}
finally語句塊之後的代碼一定會執行
        不一定會執行。
       無論有沒有異常出現,只要出現了throw,那麼就不會執行
        如果沒有異常且try和catch語句塊中沒有return,則一定會執行。
        如果有異常,那就看有沒有catch語句塊:如果有catch語句塊且出現的異常是匹配的,那麼會執行,否則不會執行。
        匹配,是指try出現的異常是catch中異常類或者是其子類,那麼就是匹配。
try {
			int count = 5/0;
//		} catch (ArithmeticException e) {
//			// TODO: handle exception
//			System.out.println(e.getMessage());
		} catch(Exception e) {
			System.out.println(e.getMessage());
		} finally {
			System.out.println("方法返回前必須執行的代碼塊");
		}
		System.out.println("finally語句塊之後的代碼執行了");






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