1. 程式人生 > >Java筆記---異常機制

Java筆記---異常機制

1.定義:程式在執行時出現的不正常情況

2.異常由來:把問題封裝成物件

3.問題劃分

(1)嚴重問題:Java通過Error類進行描述,對於Error一般不編寫針對性程式碼對其進行處理

(2)非嚴重問題:Java通過Exception類進行描述,可以使用針對性的處理方式進行處理。

4.無論是Error或者Exception都有一些共性內容,比如不正常情況的資訊、引發原因等,對其向上抽取,Java將其封裝成了Throwable類

5.異常的處理

try

{

需要被檢測的程式碼;

}

catch(異常類 變數)

{

處理異常的程式碼(處理方式);

}

finally

{

一定會執行的語句;

}

catch{}是用於處理異常。如果沒有catch{}就代表異常沒有被處理,如果該異常是檢測時異常,那麼必須宣告。

對捕獲到的異常常見的操作方法

String getMessage(); //獲取異常資訊

String toString(); //獲取異常名稱、異常資訊

//JVM預設的異常處理機制就是在呼叫printStackTrace方法,

//列印異常的堆疊的跟蹤資訊

void printStackTrace(); //獲取異常名稱、異常資訊、異常出現的

//位置

例項

class Demo

{

//在功能上用throws關鍵字聲明瞭該功能可能會出現問題

//宣告之後,在呼叫該函式的時候,要麼對該函式可能出現

//的異常繼續丟擲

//要麼對該可能出現異常的函式進行捕獲處理,否則會出現

//編譯錯誤,可以提高安全性

int div(int a,int b) throws Exception

{

return a/b;

}

}

class ExceptionDemo

{

public static void main(String[] args)

{

Demo d = new Demo();

try

{

int x = d.div(4,0);

System.out.println("x = " + x);

}

catch (Exception e) //Exception e = new Arithmetic()

{

System.out.println("除零了");

//獲取異常資訊

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

//獲取異常名稱 異常資訊

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

//JVM預設的異常處理機制就是在呼叫

//printStackTrace()方法,列印異常堆疊的跟蹤資訊

//異常名稱 異常資訊 異常出現的位置

e.printStackTrace();

}

System.out.println("over");

}

}

6.多異常的處理

(1)宣告異常時,建議宣告更為具體的異常,這樣可以處理的更加具體

(2)宣告有幾個異常,就對應有幾個catch塊,不要定義多餘的catch塊,如果多個catch塊中出現繼承關係,則父類異常catch塊放在最下面,建議在進行catch處理時,catch塊中一定要定義具體處理方式,不要簡單的一句e.printStackTrace(),也不要就簡單的書寫一條輸出語句。

class Demo

{

//宣告該函式可能出現多異常,包括算數異常、角標越界異常

int div(int a,int b) throws ArithmeticException,ArrayIndexOutOfBoundsException

{

int[] arr = new int[a];

System.out.println(arr[4]);

return a/b;

}

}

class ExceptionDemo

{

public static void main(String[] args)

{

Demo d = new Demo();

try

{

int x = d.div(5,0);

System.out.println("x = " + x);

}

//算數異常catch塊

catch(ArithmeticException e)

{

System.out.println("被零除了" + e.toString());

}

//角標異常catch塊

catch(ArrayIndexOutOfBoundsException e)

{

System.out.println("角標越界異常" + e.toString());

}

//父類異常catch塊要放在最下面

catch(Exception e)

{

e.printStackTrace();

}

System.out.println("over");

}

}

7.自定義異常

定義類繼承Exception或RuntimeException

1,為了讓該類具備可拋性

2,讓該類具備操作異常的共性方法

3,當要定義自定義異常的資訊時,可以使用父類已經定義好的功能,將異常資訊傳遞給父類的建構函式

class MyException extends Exception

{

MyException(String message)

{

super(message);

}

}

自定義異常:按照Java的面向物件思想,將程式中出現的特有問題進行封裝。

(1)例項

/*

如何定義異常資訊

因為父類Throwable建構函式中已經把異常資訊的操作都完成了,

所以在子類的建構函式中,只需將異常資訊通過super()語句傳遞給父類

那麼就可以直接通過getMessage()方法獲取自定義的異常資訊

*/

class FushuException extends Exception

{

private int value; //導致異常的負數值

FushuException(String message,int value)

{

//顯示呼叫父類建構函式,處理異常資訊

super(message);

this.value = value;

}

public int getValue() //返回導致異常的負數值

{

return value;

}

}

class Demo

{

//定義該函式除數不允許是負數,否則出現異常

//在函式內部出現了throw丟擲自定義異常物件,那麼需要在函式上宣告來讓呼叫者處理,

//不然就在內部進行try catch處理,否則會出現編譯錯誤

//一般情況下,函式內出現異常、函式上需要宣告

int div(int a,int b) throws FushuException

{

if(b < 0)

{

//手動通過關鍵字throw丟擲一個自定義異常物件

throw new FushuException("除數出現了負數",b);

}

return a/b;

}

}

class ExceptionDemo

{

public static void main(String[] args)

{

Demo d = new Demo();

try

{

int x = d.div(4,-1);

System.out.println("x = " + x);

}

catch (FushuException e)

{

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

System.out.println("出現的負數值:" + e.getValue());

}

System.out.println("over");

}

}

(2)自定義異常中,為什麼自定義類必須繼承Exception

異常體系中有一個特點,因為異常類和物件都需要被丟擲,他們都具備可拋性,這個可拋性是Throwable這個體系中的特有特點,只有這個體系中的類和物件才可以被 throws和throw關鍵字操作

8.throws和throw的區別

(1)throws:使用在函式上,後面跟的是異常類,可以跟多個,用逗號隔開

(2)throw:使用在函式內,後面跟的是異常物件

9.RuntimeException

Exception中有一個特殊的子類異常RuntimeException(執行時異常),如果在函式內通過throw丟擲該類及該類子類異常物件,則函式上可以不用宣告,編譯時一樣通過。如果在函式上通過throws聲明瞭該類及其子類異常,呼叫者可以不用處理,編譯一樣通過。

注意:之所以不用在函式上宣告,是因為不需要讓呼叫者處理。當異常發生的時候,希望程式停止,因為在執行時出現了無法繼續運算的情況,希望程式停止後,由程式設計師對程式碼進行修正。

自定義異常時:如果該異常的發生,無法在繼續進行運算,就讓自定義異常繼承RuntimeException

9.異常分兩種

(1)編譯時被檢測的異常

該異常在編譯時,如果沒有被處理(沒有丟擲也沒有try),則編譯失敗。該異常被標識,代表可以被處理。

(2)編譯時不被檢測的異常(執行時異常、RuntimeException類以及其子類)

在編譯時,不需要處理,編譯器不檢查。該異常發生時,建議不處理,讓程式停止,需要對程式碼就行修正。

10.應用例項

class NoPlanException extends Exception //無法上課的異常

{

NoPlanException(String message)

{

super(message);

}

}

//電腦藍屏異常

class lanPingException extends Exception

{

lanPingException(String message)

{

super(message);

}

}

//電腦冒煙異常

class maoYanException extends Exception

{

maoYanException(String message)

{

super(message);

}

}

class Computer

{

private int statc = 3; //狀態值為1,表示電腦正常

public void run() throws lanPingException,maoYanException

{

if(statc == 2) //狀態值為2,表示電腦藍屏

{

throw new lanPingException("電腦藍屏了");

}

if(statc == 3) //狀態值為3,表示電腦冒煙

{

throw new maoYanException("電腦冒煙了");

}

System.out.println("電腦執行");

}

public void reset() //電腦重啟

{

statc = 1;

System.out.println("電腦重啟");

}

}

class Teacher

{

private String name;

private Computer cmpt;

Teacher(String name)

{

this.name = name;

cmpt = new Computer();

}

public void jiangke() throws NoPlanException

{

try

{

cmpt.run();

}

catch (lanPingException le)

{

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

cmpt.reset(); //電腦重啟

}

catch (maoYanException me)

{

throw new NoPlanException("上課無法繼續" + me.getMessage());

}

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

}

}

class ExceptionDemo

{

public static void main(String[] args)

{

Teacher t = new Teacher("小李");

try

{

t.jiangke();

}

catch (NoPlanException e)

{

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

System.out.println("換個老師或放假");

}

}

}

11.finally程式碼塊

(1)定義一定執行的程式碼,通常用於關閉資源的程式碼,因為資源必須釋放。

(2)finally{}只有一種情況不會執行,當執行到System.exit(0)時,finally不會執行。

下面異常處理格式也是允許的

try

{}

final

{

//關閉資源

}

12.異常在子父類中覆蓋的體現

(1)子類在覆蓋父類時,如果父類的方法丟擲異常,那麼子類的覆蓋方法,只能丟擲父類的異常或者該異常的子類,或者不拋異常

(2)如果父類方法丟擲多個異常,那麼子類在覆蓋方法時,只能丟擲父類異常的子集

(3)如果父類和介面的方法中沒有異常丟擲,那麼子類在覆蓋方法時,也不可以丟擲異常,如果子類方法中發生了異常,則必須在子類方法中進行try處理,絕對不能拋

13.異常的好處

(1)將問題封裝成物件

(2)將正常流程程式碼和問題程式碼相分離,方便於閱讀

14.異常的處理原則

1,處理方式有兩種,try或者throws

2,呼叫到有丟擲異常的功能時,丟擲幾個就處理幾個

3,多個catch,父類中的catch要放在最下面,否則編譯失敗

4,catch內需要定義針對性的處理方式,不要簡單的定義

printStackTrace、輸出語句,也不要不寫

當捕獲到的異常,本功能處理不了的時候,可以繼續在catch

中丟擲

try

{

throw new AException();

}

catch(AException e)

{

throw BException;

}

如果該異常處理不了,但並不屬於該功能出現的異常,可以將異常轉換後,再丟擲和該功能相關的異常

或者異常可以處理,但需要將異常產生的和本功能相關的問題提供出去,讓呼叫者知道,並處理。也可以將捕獲異常處理後,轉換新的異常。

try

{

throw new AException();

}

catch(AException e)

{

處理AException異常

//丟擲AException異常產生的和本功能相關的問題

throw new BException();

}