2013-05-06 101 views
2

我正在爲一個框架的Java插件工作。Java異常處理 - 這是一個好的做法嗎?

我寫我的代碼以這樣一種方式,入口函數看起來像下面(認爲這是出發點,主要功能)

function entryPoint() 
{ 
    try{ 
     //some code block 
     subFunction1(); 
     subFunction2(); 
    } 
    catch(Exception e) {} 
    catch(IOException ioe) {} 
    catch(NullPointerException npe){} 
} 

function subFunction1() throws IOException 
{ 
    //some code 
} 

function subFunction2() throws NullPointerException 
{ 
    //some code 
} 

這樣的想法是,所有的子功能將引發特定的例外主要功能和 我們捕捉這些例外的主要功能,並做處理。

這是正確的嗎?如果不是,請提出更好的方法。

+1

首先捕捉'Exception'至少不會做任何事情。但無論如何,這是太多的宗教/意見與異常處理... – NilsH 2013-05-06 08:08:24

+3

你永遠不應該趕上你自己的NPE。它們表示一個*編碼*錯誤,應該是固定的,而不是被捕獲。 – dlev 2013-05-06 08:10:09

+0

@NilsH:是的。我發現多個堆棧溢出的答案,這表明多種方法。但是這種方法不是一個好的設計? – balanv 2013-05-06 08:10:40

回答

10
  • 應該更改catch聲明的順序。由於第一個catch將匹配所有Exceptions,因此以下兩個決不會被觸發。

  • 在大多數情況下,NPE是意想不到且無法恢復的。捕捉它意味着應用程序能夠從中恢復並運行。這是真的嗎?

  • 即使NPE是可恢復的,最好檢查!= null而不是依賴命令流的異常。這是出於概念上的原因(基於異常的命令流需要更多的代碼,可讀性較差,意圖通常不清楚)以及性能方面的原因。

  • 所有Exceptions都被吞下 - 沒有記錄或重新發生。這樣,沒有人會知道是否以及何時出現問題,因爲沒有例外記錄。在大多數情況下,用戶,其他開發人員和維護人員都期望幾乎所有的異常都是非常特殊的,因此被記錄。

0

我認爲這種方法是完美的。人們應該嘗試處理特定的異常,而不是一個個處理。把一個try-catch塊放在這裏就不是它的用處,而是濫用try-catch的東西。

是的異常應該是最後一個要處理的。被誤解了。

總之,你的意圖是好的,在語法上你可以依賴編譯器。

1

不要捕捉或拋出NullPointerException和異常的catch塊應該是最後一個

0

你應該做你會做,如果是沒有插件的異常處理方式相同。這取決於你的應用程序,如果你可以在一個主要方法中處理所有異常。如果存在可以繼續工作的情況,那麼這可能很困難。

我會做的關於插件的唯一事情是所有周圍的「全部」,也許還有一些特殊的情況下做一些更詳細的日誌記錄。如果框架本身沒有這樣做,這也只是要做。

0

我認爲最好是在第一個可能的位置捕捉​​異常,以便實際解決所產生的問題。

一個例子:

function int divide(int a, int b) throws DivisionByZeroException { 
    if(b == 0){ 
     throw new DivisionByZeroException(); 
    } 
    return a/b; 
} 

function int doCalculationsAndStuff(int a, int b) throws DivisionByZeroException { 
    int result = divide(a, b); 
    ... 
    return result; 
} 

function void main() { 
    try { 
     int a = userInput(); 
     int b = userInput(); 
     int result = doCalculationsAndStuff(a, b); 
     print("result: " + result); 
    } catch(DivisionByZeroException e) { 
     print("Division by zero happened. But i catched it for you =)."); 
    } 
} 

這將沒有意義的處理異常divide()doCalculationsAndStuff()。因爲在除零的情況下你會返回什麼價值?什麼都沒有,這就是爲什麼我們拋出異常,並在main函數中處理它,我們給我們的計算器應用程序的用戶一些反饋。

現在回到你的問題。如果entryPoint函數是第一個可以解決子函數中出現的問題的地方,那麼這是一個處理它們的好地方。