1.處理(handle) : 直接捕獲異常並處理。

處理異常動作:使用異常處理區塊(try-catch-finally)

  1. try:區塊內放置可能拋出異常語句。
  2. catch:區塊內處理異常的動作,動作步驟為產生異常後,try區塊停止動作,JVM尋找相關的catch區塊。可能會有多個catch區塊,異常會交給第一個符合的catch 區塊處理。
  3. finally:無論try catch 是否會執行,finally區塊一定會執行

處理異常規則:
try之後必須接著catch 或是 finallycatchfinally可以一起出現,但必須至少有一個。
在多個catch 區塊的情況下,經驗法則為從最具體排到最一般。
選擇處理的優點:在本地端直接處理,容易找到發生問題點,方法調用者不須多寫處理。
選擇處理的缺點:缺少通用性,無法選擇其他的處理方式,因為必須多寫處理的代碼因此增加該方法的複雜度。


 
 

2.聲明(declare) : 聲明該方法拋出異常,讓呼叫端接手處理。

聲明異常動作:在方法宣告中加上 throws ExceptionName
聲明異常的規則:

  1. 必須聲明方法中可能拋出的可檢測異常(checked exception),非檢測異常(unchecked exception)不是必須的,可聲明也可以不聲明。
  2. 聲明異常類別可以是其異常子類。

選擇聲明原因:

  1. 需要傳送異常發送到系統其他部份。
  2. 無法在本地端處理異常。

 
 

3.選擇處理或是聲明異常

經驗法則:盡可能處理異常,若無法處理才聲明異常。
 


 
 

4.標準異常處理選項

1.紀錄異常相關訊息

  • 使用標準輸出或錯誤流
  • 開發自定義類
  • 使用java 紀錄api (java.util.logging)

2.要求客戶端輸入訊息
透過GUIclient 選擇下一步
3.使用預設值或替換數據

  • 簡單情況將預設值設定為靜態常量加在程式碼中。
  • 複雜情況可將預設值紀錄在配置文件(Properties)中,並在發生問題時載入。

4.將控制轉移到應用程序的其他部份

  • 簡單情況提取catch 處理方法
    try {
          result = bufferReader.readLine();
        } catch (IOException e) {
            handleReadLineException();
        }
    }
    private void handleReadLineException(){
    // do handle exception for read line
    }
  • 複雜情況開發一個異常處理類別,來集中處理應用程序代碼

5.將異常轉換成其他形式

  • 可提供更適當的上下文用來描述異常
private void connect(String ip) throws ServerConnectionException
{
        try {
            //some exception
        } catch (IOException e) {
            throw new ServerConnectionException ("specify message from Server Connect", e);
        }
}

6.準備停止系統

  • 有打開的文件就關閉
  • 有連接的資源就關閉
  • 儲存必要資訊
  • 通知其他部份應用程序即將結束

7.重試操作

  • 等待一段時間後重試操作
try {
            connect();
    } catch (IOException e) {
            retryConnect();
    }
private void retryConnect()
{
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        try{
            connect();
        }catch(IOException e){
            //retry connect
        }
    }

 
8.替換或恢復操作

  • 如無法儲存在伺服器上就改為存在本機硬碟
       try {
            saveToServer();
        } catch (IOException e) {
            saveToLocalDisk();
        }
    private void saveToLocalDisk(){
    }

 
9.忽略問題

  • 當異常對系統其他部份沒有影響,如調用 I/O stream的關閉方法
private FileReader mFileReader;
...
...
try {
      mFileReader.close();
} catch (IOException e)
{
      e.printStackTrace();
}

 


 
 

5.解決異常建議事項

  • 盡可能處理異常:盡可能處理,除非條件不予許再考慮聲明異常。
  • 具體問題具體解決:需要為特定類型的問題建立特定的處理區塊。
  • 紀錄可能影響應用程序運行的異常:可以採取永久的方式紀錄影響應用程序的異常,可以幫助處理問題
  • 根據情況將異常轉換為業務上下文:建立異常的成本不高,可以考慮為特定的問題轉換特定的異常。

 
 

6.解決異常不建議事項

  • 不要忽略異常
try {
      printStream = new PrintStream(new File("./error_record"));
      System.setOut(printStream);
      printStream.println("error message");
     } catch (FileNotFoundException e)
{//do nothing here}

 

  • 不要使用覆蓋式異常處理
    try {
          printStream = new PrintStream(new File("./error_record"));
          System.setOut(printStream);
          printStream.println("error message");
        } catch (Exception e) {
               // do something
        }
  • 不要將特定異常轉為一般異常
    try {
          printStream = new PrintStream(new File("./error_record"));
          System.setOut(printStream);
          printStream.println("error message");
        } catch (IOException e) {
                throw new Exception(exceptionMessage);
        }
  • 不要處理能夠避免的異常(使用判斷式取代拋出異常)
  • 使用
    if(printStream != null){
        printStream.println("error message");
    }
    取代
    try{
         printStream.println("error message");
    }catch(NullPointerException e){
         System.out.println(''PrintStream is null'');
    }