例外處理 例外的基本觀念 多重例外處理 throw 與 throws
何謂 Bug ? “Bug”中文的解釋即是臭蟲、小蟲的意思 程式上的錯誤依性質可分為以下 3 種: 程式語法上的錯誤: char c = “SCJP”; File f = new File(“xxx”); // 忘了 import java.io.*; 執行時期的錯誤: 陣列元素索引值超出最大範圍。 整數除以 0。 邏輯的錯誤: 利息的計算公式、公司獎金配發比例以及是否要進位(四捨五入) …等。
例外的基本觀念 例外的基本觀念 在執行程式時,經常發生一些不尋常的狀況。例如: 要開啟的檔案不存在。 陣列的索引值超過了陣列容許的範圍。 使用者輸入錯誤。 Java把這類不尋常的狀況稱為「例外」(exception)。 為何需要例外處理? 易於使用 可自行定義例外類別 允許我們拋出例外 不會拖慢執行速度
public static void main(String args[]) int arr[]=new int[5]; // 容許5個元素 程式範例 // app13_1, 索引值超出範圍 public class app13_1 { public static void main(String args[]) int arr[]=new int[5]; // 容許5個元素 arr[10]=7; // 索引值超出容許範圍 System.out.println("end of main() method !!"); } Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException at app13_1.main(app13_1.java:7)
定義例外的處理 定義例外的處理的語法如下: try { // 要檢查的程式敘述; } catch(例外類別 變數名稱) // 例外發生時的處理敘述; finally // 一定會執行的程式碼; try 區塊 catch 區塊 fnally 區塊 程式一定會執行的區塊,可不寫
定義例外的處理: try 撰寫程式的時候,可將容易發生Exception的程式碼先利用 try 區塊包住。 catch 如果有發生Exception時,利用 catch 區塊攔截錯誤訊息並執行此區塊內的程式碼。 finally 用在程式”跳離” try-catch 區塊之前必須執行的程式區段,不論程式是否有例外(Exception)發生。finally 區段是 always execute 的程式區段。 try – catch Error handling
常見的 Exception: 執行期例外 說明 ArithmeticException 數學運算時的例外。例如:某數除以0。 ArrayIndexOutOfBoundsException 陣列索引值超出範圍。 NegativeArraySizeException 陣列的大小為負數。 NullPointerException 物件參照為null,並使用物件成員時所產生的例外。 IOException 當輸入異常時所產生的例外。 ParseException 分析時發生的錯誤所產生的利外。 Exception 通用性例外類別,若不清楚可能會發生的例外,可以用此來代表。 NumberFormatException 數值格式不符所產生的例外。
this line is always executed!! end of main() method!! // 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 } 如果捕捉到例外,Java會利用例外類別建立一個類別變數 e: 如果拋例外,便執行此區塊的程式碼 app13_2 OUTPUT index out of bound!! this line is always executed!! end of main() method!!
ArrayIndexOutOfBoundsException // 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 } System.out.println("end of main() method !!"); 17 } 18 } 丟出例外 ArrayIndexOutOfBoundsException 被對應的catch捕捉 app13_3 OUTPUT index out of bound!! Exception=java.lang.ArrayIndexOutOfBoundsException end of main() method !!
例外處理入門 不適當的例外處理方式 較為正確的處理方式 例外處理最好只用於錯誤處理,而不應是用於程式業務邏輯的一部份,因為例外的產生要消耗資源。 while(true) { try System.out.println(args[i]); i++; } catch(ArrayIndexOutOfBoundsException e) // .... for(int i = 0; i < args.length; i++) { System.out.println(args[i]); } 不適當的例外處理方式 較為正確的處理方式
上機練習 試寫一個程式,讓使用者輸入(1~2)數字,代表甲班和乙班來選擇班級,並列印您的班級、作號、姓名,若輸入的不是數字則處理此例外,輸出”請小心輸入!!”。
多重例外處理 多重例外處理語法架構: try { …// Statement } catch(Exception1 e1) catch(Exception2 e2)
NullPointerException IndexOutOfBoundsException FileNotFoundException 例外類別的繼承架構 : 例外類別可分為兩大類:java.lang.Exception與java.lang.Error。 StackOverflowError OutOfMemoryError VirtualMachineError AWTError AssertionError Error Exception j2sdk 1.4 Throwable ArithmeticException NullPointerException IndexOutOfBoundsException RuntimeException IOException EOFException FileNotFoundException
多重例外處理的順序:有繼承關係時,先子後父 try { …// Statement } catch(FileNotFoundException e1) catch(Exception e2) Exception下的子類別 父類別
NullPointerException IndexOutOfBoundsException FileNotFoundException StackOverflowError OutOfMemoryError VirtualMachineError AWTError AssertionError Error Exception j2sdk 1.4 Throwable ArithmeticException NullPointerException IndexOutOfBoundsException RuntimeException IOException 父類別 EOFException FileNotFoundException 子類別
將例外事件一層層的往上丟直到被處理為止,這整個過程就稱為 Call Stack Mechanism。 JVM 接到 main() { A() { B() { JVM會自行處理 所接到的例外事件! C() { Error 發生! 系統丟出了一個 Exception 事件
Call Stack 與 try-catch main() { A() { B() { try { C() { …//丟出一個Exception } catch (Exception) { …// 錯誤處理程式!
接著上一個上機練習,處理陣列索引超出範圍例外,列印例外訊息“陣列索引超出範圍”。接著再處理數字格式例外,列印例外訊息” 請輸入數字”。
throw 與 throws 拋出例外有下列兩種方式: 於程式中拋出例外(throw)。 指定method拋出例外(throws) 。
throw 與 throws 於程式中拋出例外(throw): throw 關鍵字是用來呼叫或傳遞一個例外,所以我們可以利用它在程式中觸發一個例外錯誤。 throw所丟出的例外物件同樣可以使用try-catch敘述處理。 throw 的程式語法: 丟出一個例外物件變數 throw 例外物件變數; 丟出一個匿名的例外物件 throw new Exception(錯誤訊息字串);
程式範例 { public static void main(String args[]) int a=4,b=0; try public class app13_4 { public static void main(String args[]) int a=4,b=0; try if(b==0) throw new ArithmeticException(); // 拋出例外 else System.out.println(a+"/"+b+"="+a/b); // 若沒有拋出例外,則執行此行 } catch(ArithmeticException e) System.out.println(e+" throwed"); /* app13_4 OUTPUT*/ java.lang.ArithmeticException throwed
程式範例 public class throwSample { public static void main(String[] args) try throw new Exception("測試錯誤訊息!"); } catch(Exception e) System.out.println("例外發生:" + e.toString());
throws : 撰寫Java程式時,若方法(method)中會產生一個例外錯誤,則可在宣告方法時加上 throws 關鍵字,來修飾該方法。 throws 的程式語法: 方法名稱(參數列) throws ext1,ext2 … { ….. } throws 一定要擺在”方法參數列後面”以及“{“(方法實作開始符號)前。
程式範例 public class throwsSample { public static String aMethod() throws Exception return "測試錯誤訊息!"; } public static void main(String[] args) try System.out.println(aMethod()); catch(Exception e) {}
public static void aaa(int a,int b) throws ArithmeticException int c; public class app13_6 { public static void aaa(int a,int b) throws ArithmeticException int c; c=a/b; System.out.println(a+"/"+b+"="+c); } public static void main(String args[]) try aaa(4,0); catch(ArithmeticException e) System.out.println(e+" throwed"); /* app13_6 OUTPUT */ java.lang.ArithmeticException: / by zero throwed
試在主類別中宣告一個類別方法Sum(int n) 。 上機練習 試在主類別中宣告一個類別方法Sum(int n) 。 判斷傳入的參數 n 是否小於零,如果是,則拋出一個IllegalArgumentException(“n應為正整數”) 例外。 累加1~n得數字和,並將其值返回。 在主方法中完成下列要求: 使用者可以輸入一個整數,若所輸入的不是整數,則拋出一個NumberFormatException例外,同時列印”請輸入整數”。 若使用者輸入的整數 < 0,則拋出IllegalArgumentException列外。 將數字 1~n 的總和列印在銀幕上。
Home Work 請設計一個成績輸入程式,若成績超過100分,則拋出例外顯示”除了天才外,不可能超過100分”;若低於 0 分,則拋出例外顯示”您要向學生借分數嗎?”。