14. JavaSE-異常

異常:在運行時,發生不正常的情況


在java中用類的形式對不正常情況進行了描述和封裝對象


描述不正常情況的類,就稱爲異常類


以前正常流程代碼和問題處理代碼相結合

現在將正常流程代碼和問題處理代碼分離,提高閱讀性


其實異常就是java通過面向對象的思想將問題封裝成了對象,用異常類對其進行描述

不同的問題用不同的類進行具體描述

 

異常的體系:

問題很多,意味着描述的類也很多,將其向上抽取,形成了異常體系

最終問題(不正常情況)就分成了兩大類:一般不可處理的  和  可處理的兩大類;


java中,對於不可處理的,一般用Error類來表示,對於 可處理的 , 一般用Exception來示。    

Throwable(可拋):無論是error,還是exception,都是問題,問題發生就應該拋出,讓調用者知

道並處理(該體系的特點就在於Throwable及其所有的子類都具有可拋性;對於不具有可拋性的問

題是不能進行拋出的)


可拋性到底是什麼?其實是通過兩個關鍵字來體現的; throws 和 throw這兩個關鍵字,凡是被這

兩個關鍵字所操作的類和對象都具備可拋性。

一般不可處理的。Error

特點:是由jvm拋出的嚴重性問題。這種問題一般不針對進行處理,直接修改程序。

    

該體系的特點:子類的後綴名都是用其父類名作爲後綴,閱讀性很強。

1. 一般不可處理的。Error

2. 可處理的。Exception


下面的程序爲throw關鍵字示例

    class Demo

    {

        public int method(int[] arr, int index)

        {

            if (arr == null)

            {

                throw new NullPointerException("這是一個空指針異常,哥們兒、你太瘋狂啦!");

            }

            if (index >= arr.length)

            {

                throw new ArrayIndexOutOfBoundsException("數組的角標越界啦,哥們兒、你是不是瘋啦?");

            }

            if (index < 0)

            {

                throw new ArrayIndexOutOfBoundsException("數組的角標不能爲負數,哥們兒、你真的是瘋啦!");

            }

            return arr[index];

        }

    }

    class  ExceptionDemo

    {

        public static void main(String[] args) 

        {

            int [] arr = new int[]{1,2,3};

            Demo d = new Demo();

            int num = d.method(arr,2);

            System.out.println("這是正確的輸出" + num);

            int num1 = d.method(arr,3);

            System.out.println("這是異常的情況");

            System.out.println("這裏是主程序結束的標誌");

        }

    }


對於角標是整數不存在,可以用角標越界表示

對於負數爲角標的情況,準備用負數角標異常來表示

負數角標這種異常在java中並沒有定義過,那就按照java異常的創建思想,面向對象,將負數角標進行自定義描述,並封裝成對象。這種自定義的問題描述稱爲自定義異常。


注意:如果讓一個類稱爲一個異常類,則必須繼承異常體系,因爲只有繼承異常體系的子類纔有資格具備可拋性,纔可以被兩個關鍵字所操作(throw 和 throws

    class ArrayFuShuIndexException extends Exception

    {

        ArrayFuShuIndexException(){}

        ArrayFuShuIndexException(String msg)

        {

            super(msg);

         }

    }

    class Demo1

    {

        public int method(int[] arr, int index) throws ArrayFuShuIndexException

        {

            if (arr == null)

            {

                throw new NullPointerException("這是一個空指針異常,哥們兒、你太瘋狂啦!");

            }

            if (index >= arr.length)

            {

                throw new ArrayIndexOutOfBoundsException("數組的角標越界啦,哥們兒、你是不是瘋啦?");

            }

            if (index < 0)

            {

                throw new ArrayFuShuIndexException("數組的角標不能爲負數,哥們兒、你真的是瘋啦!");

            }

            return arr[index];

        }

    }

    class  ExceptionDemo1

    {

        public static void main(String[] args)  throws ArrayFuShuIndexException

        {

            int [] arr = new int[]{1,2,3};

            Demo1 d = new Demo1();

            int num = d.method(arr,2);

            System.out.println("這是正確的輸出" + num);

            int num1 = d.method(arr,-1);

            System.out.println("這是異常的情況");

            System.out.println("這裏是主程序結束的標誌");

        }

    }

 

異常(Exception)的分類:

1. 編譯時被檢測的異常:只要是Exception和其子類都是,除了特殊子類RuntimeException體系;編譯時異常問題一旦出現,希望在編譯時就進行檢測,讓這種問題有對應的處理方式,這樣的問題都可以針對性處理

2. 編譯時不檢測的異常(運行時異常):就是Exception中的RuntimeException和其子類;這種問題的發生,無法讓功能繼續,運算無法進行,更多的時候是調度者導致的。或者引發了內部狀態的改變導致的。那麼、這種問題一般不進行處理,直接編譯通過,在運行時,讓調用時的程序強制停止。讓調用者對代碼進行修正。

 

自定義異常時,要麼繼承Exception,要麼繼承RuntimeException

 

Throws 和 throw區別:

1. Throws 使用在函數上;Throw使用在函數內

2. Throws拋出的是異常類,可以拋出多個,用逗號隔開;throw拋出的是異常對象

 

異常處理的捕捉形式:

這是可以對異常進行針對性的處理方式

異常處理格式:

Try

{放需要被檢測異常的代碼}

Catch(異常類 變量) //該變量用於接收發生的異常對象

{真正處理異常的代碼}

Finally

{一定會被執行的代碼}


class ArrayFuShuIndexException extends Exception

{

    ArrayFuShuIndexException(){}

    ArrayFuShuIndexException(String msg)

    {

        super(msg);

    }

}

class Demo1

{

    public int method(int[] arr, int index) throws ArrayFuShuIndexException

    {

        if (arr == null)

        {

            throw new NullPointerException("這是一個空指針異常,哥們兒、你太瘋狂啦!");

        }

        if (index >= arr.length)

        {

            throw new ArrayIndexOutOfBoundsException("數組的角標越界啦,哥們兒、你是不是瘋啦?");

        }

        if (index < 0)

        {

            throw new ArrayFuShuIndexException("數組的角標不能爲負數,哥們兒、你真的是瘋啦!");

        }

        return arr[index];

    }

}

class  ExceptionDemo1

{

    public static void main(String[] args)

    {

        int [] arr = new int[]{1,2,3};

        Demo1 d = new Demo1();

        int num ;

        try

        {

            num = d.method(arr,-1);

        }

        catch (ArrayFuShuIndexException e)

        {

            System.out.println(e.getMessage());

            System.out.println("數組角標不能爲負數");

        }

        catch (ArrayIndexOutOfBoundsException e)

        {

            System.out.println("數組越界");

        }/*

        catch (NullPointerException e)

        {

            System.out.println("傳入的數組爲空指針");

        }*/

        catch (Exception e)

        {

            e.printStackTrace();

        }

        finally

        {

            System.out.println("程序退出");

            System.exit(1);

        }

    }

}

注意:jvm的異常處理機制默認就是調用printStackStrace方法

但實際上,如果有生成日誌的需求,均是使用第三方工具,例如log4jlog4jlog for java

注意:在多catch的情況下,父類的catch一定要放在子類的catch之下(代碼上下位置)

 

異常處理原則;

1. 函數內容如果拋出需要檢測的異常,那麼函數上必須聲明,否則必須在函數內用try catch捕捉,

   否則編譯失敗

2. 如果調用到了聲明異常的函數,那麼try catch要麼throws,否則編譯失敗

3. 什麼時候catch,什麼時候throws

功能內容可以解決,用catch,解決不了,用throws告訴調用者,由調用者解決

4. 一個功能如果拋出多個異常,那麼調用時,必須有多個catch進行針對性的處理;內部有幾個

   需要檢測的異常,就拋幾個異常,拋出幾個,就catch幾個!

 

異常--finally代碼塊:通常用於關閉程序中打開的資源

有一種情況,finally代碼塊不會執行,就是在finally之前執行語句中,包含System.exit()語句。否則、無論是否發生異常,finally都一定會執行。

Try catch finally代碼塊組合特點:

1. Try catch finally

2. Try catch(多個),當沒有必要資源需要釋放的時候,使用這種方式

3. Try finally,可用於當出現異常的時候,確保資源立即釋放掉,對於出現的異常,可能本類無法處理,交給其他的類來進行處理。


Void show() throws Exception

{

Try

{

Throw new Exception();

}

Finally

{}

}

下面是個例子

    class Demo2

    {

        public int method(int[] arr, int index)

        {

            if (index >= arr.length)

            {

                throw new ArrayIndexOutOfBoundsException("數組的角標越界啦,哥們兒、你是不是瘋啦?");

            }

            return arr[index];

        }

    }

    class  ExceptionDemo2

    {

        public static void main(String[] args)

        {

            int [] arr = new int[]{1,2,3};

            Demo2 d = new Demo2();

            int num ;

            try

            {

                num = d.method(arr,10);

            }

            catch (ArrayIndexOutOfBoundsException e)

            {

                System.out.println("數組越界");

            }

            finally

            {

                System.out.println("程序退出");

                System.exit(1);

            }

        }

    }

Finally作用很大,例如 實際開發中連接數據庫的代碼,一旦查詢的時候,發生異常,此時就可以在finally中關閉數據庫的連接,如果不關閉,很容易耗盡數據庫的連接資源。

 

異常應用:

 /*

    老師用電腦上課

 

    問題領域中涉及兩個對象

    老師、電腦

 

    分析其中的問題。

    比如電腦藍屏、冒煙啦

*/

    class LanPingException extends Exception

    {

        LanPingException(String msg)

        {

            super(msg);

        }

    }

 

    class MaoYanException extends Exception

    {

        MaoYanException(String msg)

        {

            super(msg);

        }

    }

 

    class NoPlanException extends Exception

    {

        NoPlanException(String msg)

        {

            super(msg);

        }

    }

 

    class Computer

    {

        private int state = 2;

        public void run() throws LanPingException,MaoYanException

        {

            if (state == 1)

            {

                throw new LanPingException("電腦藍屏啦");

            }

            if (state == 2)

            {

                throw new MaoYanException("電腦冒煙啦");

            }

            System.out.println("老師上課的電腦");

        }

 

        public void reset()

        {

            state = 0;

            System.out.println("電腦已經進行重啓");

        }

    }

 

    class Teacher

    {

        private String name;

        private Computer comp;

        Teacher(String name)

        {

            this.name = name;

            comp = new Computer();

        }

        Teacher(){}

 

        public void prelect() throws NoPlanException

        {

            try{

                comp.run();

                System.out.println("講課");

            }catch (LanPingException e)

            {

                System.out.println(e.toString());

                comp.reset();

                prelect();

            }catch (MaoYanException e)

            {

                System.out.println(e.toString());

                test();

                throw new NoPlanException("對電腦進行維修,課時任務無法完成");

            }

        }

 

        public void test()

        {

            System.out.println("大家開始練習");

        }

    }

    class  ExceptionTest

    {

        public static void main(String[] args)

        {

            Teacher t = new Teacher("zhangsan");

            try

            {

                t.prelect();

            }

            catch (NoPlanException e)

            {

                System.out.println("換人...............");

            }

        }

    }

 


=====================================================

    class NoAddException extends Exception

    {}

 

    void addData(Data d) throws NoAddException

    {

        連接數據庫

        try

        {

            添加數據,出現異常 SQLException

        }

        catch (SQLException e)

        {

            throw new NoAddException();

        }

        finally

        {

            關閉數據庫

        }

    }

*/

 

異常注意事項:

1. 子類在覆蓋父類方法時,父類的方法如果拋出了異常,那麼子類的方法只能拋出父類的異常或者該異常的子類。

2. 如果父類拋出多個異常,那麼子類只能拋出父類異常的子集

簡單而言、實就是子類覆蓋父類只能拋出父類的異常或者子集

注意:如果父類的方法沒有拋出異常,那麼子類覆蓋時絕對不能拋。就只能try

 

Object:所有類的父類

Object是不斷的抽取,具備着所有對象都具備的共性內容

 

 


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