2015年2月8日 星期日

物件導向 ─ 例外處理

例外處理


Q: 何謂例外處理?

用來處理程式執行發生了不是程式撰寫錯誤的異常情況的處理方式

Q:適用的時機?

例如:無法連上資料庫、找不到所需的檔案、陣列註標值超過範圍的時候....等

Q:所有的Exception都要處理嗎?

YES!    但唯獨RuntimeException以及子類別不必處理   <<請看下圖>>



Q:為什麼RuntimeException(UncheckedException <執行期例外>)不用處理?

因為complier不會幫忙檢查,且當加了"throws",Java希望"RuntimeException",由程式設計師自己抓bug就行了
不必try catch 把問題秀出來

Q:為什麼要用try catch?
目的是要讓使用者知道目前發生了什麼問題,例如:"輸入資料型態有誤,請重新輸入" or "目前無法連線到資料庫"...等


本篇著墨在黑色方格的內容

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

例外處理方式: try catch

try { 可能發生例外情況的敘述(程式碼)}

catch (Exception種類  參數 ){ 例外狀況發生的處理程序}   

※ 只能有一個 try{} 區塊
※ 可以有N個 catch{} 區塊  <<類別位階低(子類別)的放前面類別位階高(父類別)的要放後面>>

Exception常見種類:
                                      ○  IOException 
                                      ○  SQLException
                                      ○  ClassNotFoundException   
                                      ○  InterruptedException

又稱為 CheckedException(受檢例外)


範例:



public class Exception {
     public static void main(String [] args){
         try{
             method();
             System.out.println("No problems");
             
         }catch(IOException  ioe){

             System.out.println("catch IOException");

         }catch(SQLException  sql){

             System.out.println("catch SQLException");

         }catch(Exception e){

             System.out.println("catch Exception");

         }finally{
                          System.out.println("finally message");
         }
                         System.out.println("end");
     
    }
    
}

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
情況1:Method(); 執行成功且沒有任何錯誤

Result:No problem
            finally message
            end
--------------------------------------------------------------------------------------------------------             
情況2:Method(); 發生IOException

Result:catch IOException
            finally message
            end
--------------------------------------------------------------------------------------------------------             
情況3:Method(); 發生SQLException

Result:catch SQLException
            finally message
            end
--------------------------------------------------------------------------------------------------------             
情況4:Method(); 不是IOException也不是SQLException,則會由Exception接住

Result:catch Exception
            finally message
            end

※ Exception 可以接住所有種類的Exception,因此不建議只使用Exception捕捉錯誤
在偵錯時,比較麻煩要一一測試所有可能發生的問題點
--------------------------------------------------------------------------------------------------------       
情況5:Method(); 假設沒有設定catch (Exception e),且抓不到錯誤

Result:  finally message
          
 ※ finally :不論是否有發生例外都會跑finally這一行程式
---------------------------------------------------------------------------------------------------------

※ System.out.println("end");

當程式發生例外情形且沒有抓住錯誤,這行敘述便不會執行
當程式發生例外情形且抓住錯誤了,這行敘述便會執行


※ catch 只會抓一次,一旦抓到錯誤便會跳離Method或結束程式
=============================================================================================

throws :
若Method在實作中可能產生某些的例外情況,則需要加上throws讓使用者知道執行此方法會引發或是需要處理的情況  (標註一個方法會拋出例外。)

┼ 特性:
不能自行處理例外,且程式主控權就不在method裡,而是還到呼叫的人手上


範例:


public class Exception throws ArithmeticException{
     public static void main(String [] args){
         try{
                int i =10;
                i = 10/0;

                    System.out.println("No problems");
              }catch (ArithmeticExceptionce) {

             System.out.println("發生計算上的錯誤")
       }
                            System.out.println("end");
    }
    
}


------------------------------------------------------------------------------------------------------

自訂例外處理:自行定義例外類別();   MyException()


throw:
● 程式語法
                   throw 例外物件變數
                   throw new Exception(錯誤訊息字串)
-------------------------------------------------------------------

public class ExException {

    public static void main(String[] args) {

            tryToCalculates(10, 2);                                // 傳送兩組值實作

            tryToCalculates(10, 0);
         
        
    }
   public static void tryToCalculates (int x, int y){

           if (y == 0){                                                      // 當 y 不等於0,會直接跑else 印出結果
                     
                       try{                                                    // 當 y = 0,會執行try裡的敘述,去找MyException (1)

                        throw new MyException(0);

                       } 

                     catch  (MyException e){                         // catch 到MyException ,便執行裡面的敘述  (6)

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

                     }

           } else {

                     System.out.println("結果為: " + x / y);
        }
   }
}


class MyException extends Exception{          //   自訂例外處理為MyException 必須繼承 Exception (父類別) (2)

             private int value;                          //    建構子(必須建立)  (3)

             MyException (int value){               //  (4)

              this.value = value;                      //  (5)
            }
             
                     public String toString(){            // (7)

                               return "發生錯誤了";      //  (8)
                     }
}


-----------------------------------------------------------------------------------------------------------------------------
Result:

結果為: 5

發生錯誤了


Tips: 註解中 小括號+數字 為程式執行順序

沒有留言:

張貼留言