• 沒有找到結果。

第第十十三三章章 例例外外處處理理

N/A
N/A
Protected

Academic year: 2021

Share "第第十十三三章章 例例外外處處理理"

Copied!
27
0
0

加載中.... (立即查看全文)

全文

(1)

第 第 十 十 三 三 章 章 例 例 外 外 處 處 理 理

本章學習目標

了解什麼是例外處理

認識例外類別的繼承架構

認識例外處理的機制

學習如何撰寫例外類別

(2)

13.1 例外的基本觀念

在執行程式時,經常發生一些不尋常的狀況。例如:

(1) 要開啟的檔案不存在。

(2) 陣列的索引值超過了陣列容許的範圍。

(3) 使用者輸入錯誤。

Java 把這類不尋常的狀況稱為「例外」(exception)。

(3)

13.1.1 為何需要例外處理?

9 易於使用

9 可自行定義例外類別

9 允許我們拋出例外

9 不會拖慢執行速度

(4)

13.1.2 簡單的例外範例 app13_1 是個錯誤的程式:

01 // app13_1, 索引值超出範圍 02 public class app13_1 03 {

04 public static void main(String args[]) 05 {

06 int arr[]=new int[5]; // 容許 5 個元素 07 arr[10]=7; // 索引值超出容許範圍 08 System.out.println("end of main() method !!");

09 } 10 }

app13_1 執行時,會產生下列的錯誤訊息:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException at app13_1.main(app13_1.java:7)

(5)

Java 的預設例外處理機制會依下面的程序做處理:

(1)拋出例外

(2)停止程式執行。

(6)

13.1.3 例外的處理

例外處理:加上捕捉例外的程式碼,可針對不同的例外做妥善的處理。

例外處理的語法如下:

try {

// 要檢查的程式敘述;

}

catch(例外類別 變數名稱) {

// 例外發生時的處理敘述;

} finally {

// 一定會執行的程式碼;

}

格式13.1.1 例外處理的語法 try 區塊

catch 區塊

finally 區塊

(7)

下圖繪出了例外捕捉的流程圖:

try{} 是否捕 捉到例外 ? try{} 是否捕 捉到例外 ?

執行catch區塊裡 的敘述 執行 catch 區塊

裡的敘述 與catch() 裡 的例外相同 ?

與catch() 裡 的例外相同 ?

true

其它的敘述 其它的敘述 false

false

執行 finally 區塊 裡的敘述 執行 finally 區塊

裡的敘述 true

(8)

下面是例外處理的範例:

01 // app13_2,例外的處理 02 public class app13_2 03 {

04 public static void main(String args[]) 05 {

06 try // 檢查這個程式區塊的程式碼 07 {

08 int arr[]=new int[5];

09 arr[10]=7;

10 }

11 catch(ArrayIndexOutOfBoundsException e) 12 {

13 System.out.println("index out of bound!!");

14 }

15 finally // 這個區塊的程式碼一定會執行 16 {

17 System.out.println("this line is always executed!!");

18 }

19 System.out.println("end of main() method!!");

20 } 21 }

如果拋例外,

便執行此區塊 的程式碼 /* app13_2 OUTPUT--- index out of bound!!

this line is always executed!!

end of main() method!!

---*/

(9)

如果捕捉到例外,Java 會利用例外類別建立一個類別變數 e:

01 // app13_3, 例外訊息的擷取 02 public class app13_3 03 {

04 public static void main(String args[]) 05 {

06 try 07 {

08 int arr[]=new int[5];

09 arr[10]=7;

10 }

11 catch(ArrayIndexOutOfBoundsException e) 12 {

13 System.out.println("index out of bound!!");

14 System.out.println("Exception="+e); // 顯示例外訊息 15 }

16 System.out.println("end of main() method !!");

17 }

18 } /* app13_3 OUTPUT--- index out of bound!!

Exception=java.lang.ArrayIndexOutOfBoundsException end of main() method !!

---*/

(10)

13.1.4 例外處理機制的回顧

下圖繪出了例外處理機制的選擇流程:

例外處理機制

自行撰寫try-catch-filally 區塊來處理例外,

app13_2, app13_3

交由Java 的預設例外處理機制來處理,

app13_1

1

2

(11)

Throwable Throwable

Error

Error ExceptionException

RuntimeException RuntimeException IOException

IOException

IndexOutOfBoundsException IndexOutOfBoundsException

ArrayIndexOutOfBoundsException ArrayIndexOutOfBoundsException ArithmeticException

ArithmeticException

StringIndexOutOfBoundsException StringIndexOutOfBoundsException

... ...

... ...

... ...

... ...

13.2 例外類別的繼承架構

例外類別可分為兩大類:java.lang.Exception 與 java.lang.Error。

下圖為 Throwable 類別的繼承關係圖:

(12)

當例外發生時,catch() 程式區塊會接收由 Throwable 類別的子類別所 產生的物件:

catch( ArrayIndexOutOfBoundsException e ) {

System.out.println("index out of bound!!");

System.out.println("Exception="+e); // 顯示例外訊息 }

只接收由Throwable類別的子類別所產生的物件

(13)

使用 try 捕捉一種以上的例外

若要捕捉 ArithmeticException 和 ArrayIndexOutOfBoundsException 兩個例外,可以用如下的語法來撰寫:

01 try 02 {

03 // try 區塊的程式碼 04 }

05 catch(ArrayIndexOutOfBoundsException e) 06 {

07 // 捕捉到 ArrayIndexOutOfBoundsException 例外所執行的程式碼 08 }

09 catch(ArithmeticException e) 10 {

11 // 捕捉到 ArithmeticException 例外所執行的程式碼 12 }

(14)

捕捉所有的例外

不論例外類別為何,都想捕捉它的話,則可在 catch() 的括號內填上 Exception 例外:

01 catch(Exception e) 02 {

03 // 捕捉任何例外所執行的程式碼 04 }

(15)

13.3 拋出例外

拋出例外有下列兩種方式:

(1) 於程式中拋出例外。

(2) 指定 method 拋出例外。

(16)

13.3.1 於程式中拋出例外

於程式中拋出例外時,要用到 throw 這個關鍵字,其語法如下:

throw 由例外類別所產生的物件;

格式13.3.1 例外處理的語法

(17)

app13_4 是於程式中拋出例外的範例:

01 // app13_4, 於程式中拋出例外 02 public class app13_4 03 {

04 public static void main(String args[]) 05 {

06 int a=4,b=0;

07 08 try 09 {

10 if(b==0)

11 throw new ArithmeticException(); // 拋出例外 12 else

13 System.out.println(a+"/"+b+"="+a/b); // 若沒有拋出例外,則執行此

14 }

15 catch(ArithmeticException e) 16 {

17 System.out.println(e+" throwed");

18 } 19 }

20 } /* app13_4 OUTPUT---

java.lang.ArithmeticException throwed ---*/

(18)

app13_5 是讓系統自動拋出例外的驗證:

01 // app13_5, 讓系統自動拋出例外 02 public class app13_5

03 {

04 public static void main(String args[]) 05 {

06 int a=4,b=0;

07 08 try 09 {

10 System.out.println(a+"/"+b+"="+a/b);

11 }

12 catch(ArithmeticException e) 13 {

14 System.out.println(e+" throwed ");

15 } 16 } 17 }

/* app13_5 OUTPUT--- java.lang.ArithmeticException throwed: / by zero throwed ---*/

(19)

13.3.2 指定 method 拋出例外

若是要由 method 拋出例外,method 必須以下面的語法來定義:

method 名稱(引數...) throws 例外類別 1,例外類別 2,...

{

// method 內的程式碼 }

格式13.3.2 method 拋出例外

(20)

app13_6 是指定由 method 來拋出例外的範例。

01 // app13_6, 指定 method 拋出例外 02 public class app13_6

03 {

04 public static void aaa(int a,int b) throws ArithmeticException 05 {

06 int c;

07 c=a/b;

08 System.out.println(a+"/"+b+"="+c);

09 } 10

11 public static void main(String args[]) 12 {

13 try 14 {

15 aaa(4,0);

16 }

17 catch(ArithmeticException e) 18 {

19 System.out.println(e+" throwed");

20 } 21 } 22 }

/* app13_6 OUTPUT--- java.lang.ArithmeticException: / by zero throwed ---*/

(21)

app13_7 說明了如何從不同類別裡的 method 裡拋出例外:

01 // app13_7, 從不同類別內的 method 拋出例外 02 class Ctest

03 {

04 public static void aaa(int a,int b) throws ArithmeticException 05 {

06 int c=a/b;

07 System.out.println(a+"/"+b+"="+c);

08 } 09 }

10

11 public class app13_7 12 {

13 public static void main(String args[]) 14 {

15 try 16 {

17 Ctest.aaa(4,0);

18 }

19 catch(ArithmeticException e) 20 {

21 System.out.println(e+" throwed");

22 } 23 }

24 } /* app13_7 OUTPUT--- java.lang.ArithmeticException: / by zero throwed ---*/

(22)

13.4 自己撰寫例外類別 自行撰寫例外類別的語法如下:

class 例外類別名稱 extends Exception {

// 定義類別裡的各種成員 }

格式13.4.1 撰寫自訂例外類別 的語法

(23)

下面的範例說明了如何定義自己的例外類別,以及使用它們:

01 // app13_8, 定義自己的例外類別

02 class CCircleException extends Exception // 定義自己的例外類別 03 {

04 } 05

06 class CCircle // 定義類別 CCircle 07 {

08 private double radius;

09 public void setRadius(double r) throws CCircleException 10 {

11 if(r<0) 12 {

13 throw new CCircleException(); // 拋出例外 14 }

15 else

16 radius=r;

17 }

18 public void show() 19 {

20 System.out.println("area="+3.14*radius*radius);

21 }

method 拋出例外

(24)

22 } 23

24 public class app13_8 25 {

26 public static void main(String args[]) 27 {

28 CCircle cir=new CCircle();

29 try 30 {

31 cir.setRadius(-2.0);

32 }

33 catch(CCircleException e) // 捕捉由 setRadius()拋出的例外 34 {

35 System.out.println(e+" throwed");

36 }

37 cir.show();

38 } 39 }

/* app13_8 OUTPUT--- CCircleException throwed area=0.0

---*/

(25)

main()拋出例外讓 系統預設的例外處理 機制來處理

13.5 回顧 IOException 例外類別

會拋出 IOException 例外的 method,其例外處理的方式有兩種。

第一種是直接由 main()拋出例外,app3_13 所採用的就是這種機制:

01 // app3_13,由鍵盤輸入字串 02 import java.io.*;

03 public class app3_13 04 {

05 public static void main(String args[]) throws IOException 06 {

.. ...

16 } 17 }

(26)

第二種方式是撰寫 try-catch 區塊來捕捉拋出的例外,如下面的範例:

01 // app13_9,撰寫 try-catch 區塊來捕捉 IOException 例外 02 import java.io.*; // 載入 java.io 類別庫裡的所有類別 03 public class app13_9

04 {

05 public static void main(String args[]) 06 {

07 BufferedReader buf;

08 String str;

09

10 buf=new BufferedReader(new InputStreamReader(System.in));

11 try 12 {

13 System.out.print("Input a string: ");

14 str=buf.readLine();

15 System.out.println("string= "+str); // 印出字串 16 }

17 catch(IOException e){}

18 }

19 } /* app13_9 OUTPUT---

Input a string: Hello Java!

string= Hello Java!

---*/

(27)

參考文獻

相關文件

《小偵探》 :小朋友,你知道誰是歐巴馬嗎?請你查一查他的資料,與全班分

焚書坑儒事件發生在秦始皇三十四年(公元前 213

Britain–s £50 Note Will Honor Computing Pioneer Alan Turing.. 盧政良 台大資訊系

•  問你當前的序列裡的第 k個人是誰 (區間詢問?). • 

•  問你當前的序列裡的第 k個人是誰 (區間詢問?). • 

在 Java 例外(Exception)處理中,若在 try 區塊中配置一個資源,下述何者正確?(A)至少要 跟隨一個

1.在 1800 年晚期,有多少匹的「野馬」在美國大西部遊

可以設定遊戲音 效以及是否離開