Oct. 29 10:56~12:15
Signaling
把例外的實例(instance)傳遞給例外接收者的這個動作叫做signaling、throwing、raising或triggering,以Java為例,透過throw這個關鍵字來把例外往外拋,請參考以下程式片段:
從signaling的角度來看,例外產生的方式有可分為兩種形式:
- Synchronous exception:同步例外,因為我們所呼叫的指令或method執行失敗所產生的例外。
- Asynchronous exception:由執行環境(例如JVM)所主動丟出的例外,和目前程式所執行的指令或method沒有直接的關係。例如,執行環境偵測到內部錯誤或是記憶體不足而丟出一個例外,像是Java的OutOfMemoryError就屬於非同步例外。
大部分的例外處理設計所談論的議題在於要如何來處理同步例外,當非同步例外發生,通常表示執行環境已經產生了嚴重的錯誤,此時最好的辦法就是結束程式執行,避免一錯再錯。
***
Propagation
Propagation討論例外傳遞的問題,例如method A呼叫method B,在method B裡面產生了一個例外,但是這個例外卻沒有被method B給處理(捕捉住),則該例外可能會被傳遞到method A身上。
例外傳遞的方式分成兩種:
- Explicit:接收到例外的人,如果不想處理這個例外,則必須要明白的指出要把這個未被處理的例外往外丟。Java的checked exception就屬於這種類型,如果某個method遇到一個checked exception但卻不想處理它,則必須要把這個checked exception宣告在method signature上面。雖然在程式裡面不需要先捕捉這個checked exception然後再把它re-throw出去,但是廣義的來看,要求把不想處裡的例外宣告在介面上面,這樣也算是一種explicit propagation。
下列Java程式片段,其中aIs.readInt()與aIS.readFully(messageBody)這兩行都會丟出IOException,但是這個method並不想處理它,所以把IOException宣告在method signature上面往外傳遞。
- Implicit:接收到例外的人,如果不想處理這個例外,在預設的情況之下,例外會直接往外傳遞,不需要特意指定要把這個未被處理的例外往外丟。Java的unchecked exception,以及C#所有exception的傳遞方式,就屬於implicit的方式。
下面C#程式範例,其中第4、5兩行程式都可以會產生例外,但是因為C#的例外傳遞方式是採取implicit propagation,所以如果writeFile() method不想處理這些例外,也不需要特別指定要把它們往外丟,在預設的情況下這些沒有被捕捉的例外就會自動往上傳遞。
***
友藏內心獨白:Explicit propagation好像有點小麻煩,但有沒有好處呢?