2013年2月3日 星期日

Exception Handling (一)

在寫ANDROID上的RESTFUL Client程式時,又有了錯誤處理機制很重要的體認。

什麼才是有效又簡單的方法來處理程式可能會出現的錯誤情況?
目前的想法是分成兩部份,
一、處理
二、反映無法處理,通知接手的類別去處理。例如UI顯示網路連線有問題!
UI必需接受任何拋出的例外,處理並通知使用者!!

參考以下網址並節錄內容:

Java Essence: 要抓還是要丟?

1 、由 於操作檔案讀取的過程中,有許多方法可能丟出受檢例外(Checked Exception),你可能如上使用try..catch加以處理,在catch中以主控台方式輸出錯誤訊息,但問題在於,你並不知道你的程式庫會用在 什麼環境,是文字模式?視窗模式?或是Web應用程式?直接在catch中寫死處理處理例外或輸出錯誤訊息的方式,是一件不符合需求的方式。

2、如果你的方法設計流程中,發生例外時,當時的上下文環境並不知道該如何處理(例如你並不知道程式庫會用在什麼環境下時),那麼你可以丟出例外,讓呼叫你的方法的客戶端來處理。例如:
import java.io.*;
public class FileUtil {
    public static String readText(String file) throws FileNotFoundException {
        String text = null;
        FileReader reader = new FileReader(file)
        ...
        return text;
    }
    ....
}

3、當例外發生時,你可以使用try..catch處理當時環境下所可以作的錯誤處理,對於當時環境下無法決定如何處理的部份,可以丟出去給屆時的客戶端處理。如果你想先處理部份事項再丟出,則一個例子如下:
import java.io.*;
public class FileUtil {
    public static String readText(String file) {
        String text = null;
        FileReader reader = null;
        try {
            reader = new FileReader(file);
            ...
        }
        catch(FileNotFoundException ex) {
            // Logging 或 ex.printstackTrace()
            // 其它處理
            throw ex;
        }
        finally {
            if(reader != null) {
                try {
                    reader.close();
                }
                catch(IOException ex) {
                    // Logging 或 ex.printstackTrace()                    // 其它處理
                    throw ex;
                }
            }
        }

        return text;
    }
    ....
}
在進行完部份錯誤處理之後,你可以使用throw將例外再丟出,當你在流程中丟出例外,就直接跳離原有的流程。如果流程正常執行,最後一定要執行的動作可以放在finally區塊中。

4、一個有趣的問題是,如果程式撰寫的流程中先return了,而你也有寫finally區塊,那finally區塊還會執行嗎?答案是肯定的,finally區塊會先執行完後,再執行return。例如下面這個程式會先顯示「finally...」再顯示「1」:
public class Main {    
    public static int test(boolean flag) {
        try {
            if(flag) {
                return 1;
            }
        }
        finally {
            System.out.println("finally...");
        }
        return 0;
    }
    
    public static void main(String[] args) {
        System.out.println(test(true));
    }
}






沒有留言:

張貼留言