TAG

首都機能移轉 (2) 歌詞 (2) 靠北文 (40) 戲言 (30) 糟糕 (7) ACG (23) Assembly (2) Boost (2) C (31) C++ (69) CMake (4) CSIE (67) Debian (34) Design_Pattern (2) Django (1) Eclipse (1) en_US (13) FFmpeg (3) FoolproofProject (26) FreeBSD (2) Git (4) GNU_Linux (65) IDE (5) Java (11) JavaScript (19) KDE (15) Khopper (16) KomiX (3) Kubuntu (18) Life (1) Lighttpd (2) Mac_OS_X (2) Opera (1) PHP (2) PicKing (2) Programing (21) Prolog (1) Python (7) QSnapshot (2) Qt (30) Qt_Jambi (1) Regular_Expression (1) Shell_Script (7) Talk (98) VirtualBox (7) Visual_Studio (13) Windows (18) zh_TW (36)

2009年5月4日 星期一

Checked exceptions

Exception 是一種錯誤處理機制,可以在函式無法處理錯誤時拋出,中斷函式流程,並往上 unwind stack,直到有個 try-catch 述句把它捕捉起來為止。比起 error code 或是 assertion,它相對來說是較新的處理方式,也因為它會中斷流程,因此要達到 exception safe 就會變很困難。一些靜態語言則為了此目的提供了受檢測的異常處理模型,限制函式拋出的異常。
C++ 的寫法:
void f() throw(); // no throw
void f() throw( std::exception, std::runtime_error ); // exception and runtime_error only
不過實際上,就算宣告為 no throw,這個函式還是可以拋出其他異常,編譯器一樣會通過,只是這代表了嚴重錯誤,程式會立刻異常終止。你可以註冊一個 unexpected_handler,讓它在檢測到異常時執行這個函式,但是由於整個程式只有一個 handler,而一個程式裡有異常丢擲的函式可能不只一個,實際上來說沒什麼用。這種在執行期才檢測的模型叫動態檢測。
汲取了 C++ 教訓的 Java 則使用了更強硬的方法,實施靜態檢測,也就是在編譯期就檢查異常規格:
public f() throws IOException {}
沒有列出的異常就絕不能丢擲,一定要在函式內捕捉起來,甚至於如果有用到含有異常規格的函式,也一定要把它所列出來的所有異常都處理好。看起來好像很安全 ... 不過這真的是很煩人的設計;因為異常規格算是函式簽名的一部分,要是你修改了某個函式的實作,它改用了一個新的函式,而這個函式會拋出新的異常,因為一些設計上的缺陷無法自行處理,就有可能被迫修改異常規格,而這一改,可能會逼得其他有用到這個函式的函式也要跟著處理這個異常。
採用未受檢的異常處理模型的語言就傾向於不限制異常,沒捉到就讓它終止程式。

2 則留言:

  1. 所以Java有RuntimeException,
    可以丟出interface沒有定義的異常訊息。

    回覆刪除
  2. 其實這也是我覺得難以理解 Java 的設計方針的地方 ...
    如果它真的這麼在意異常安全,就不該局部放寬限制

    回覆刪除