2009-12-02 48 views
2

我目前正在維護一段有點「異常快樂」的代碼。基本上,任何方法或任何拋出異常。我將努力處理這個問題,但同時,我想知道在更小的代碼塊(如方法)中處理個別異常的最佳方法是什麼。它是更好地做這樣的事情:在一個方法內處理多個異常

public void aMethod() 
    try { 
    //Lots of code in here. Many lines. 
    } catch(Exception e) { 
    // TODO - Handle All Exceptions, but fairly generically 
    } 
} 

或者是這樣的:在尋找

public void bMethod() { 
    try { 
    // One line of code. 
    } catch(Exception e) { 
    // TODO - Handle a specific Exception (may even involve rethrowing it with more information) 
    } 

    // More code. 

    try { 
    // Another line of code. 
    } catch(Exception e) { 
    // TODO - Handle another specific exception. 
    } 
} 

我意識到這是一個非常基本的問題,但畢竟在數以百計的方法有例外出來的每其一,我開始懷疑如何最好地處理所有這些問題,以及這裏可能採取的最佳做法。

回答

6

首先,您應該只將代碼放在try/catch塊中,這是值得的例外。例如,有意想不到的值不一定是個例外,但是試圖從一個不存在的文件中讀取。

要回答你的主要問題,你應該把異常代碼放在同一個try {}塊中,並在主嘗試之後按照多個catch塊的粒度順序捕獲特定問題。

//Regular code that doesn't need to be covered by a try/catch block 

try { 

    //critical code only 

} catch (NullPointerException npe) { 
    //Code 
} catch (RandomException re) { 
    //code 
} catch (Exception e) { 
    //code 
} 
+0

感謝您的回答!另外,我的確瞭解異常值。不幸的是,原作者在任何地方都會拋出java.lang.Exception,這意味着我必須處理每個異常(或者我的方法必須拋出異常),所以在這一點上,我沒有得到一個選項。我將致力於一個更加連貫的解決方案。首先從嬰兒步驟開始(這是本問題的一部分)。 – JasCav 2009-12-02 21:20:17

+0

@Jason,沒問題。很高興看到人們不需要額外努力改進現有代碼。保持良好的工作! – 2009-12-02 21:40:46

1

你的bMethod是不是很有用的說明。嘗試重新編輯它。無論如何,你有兩種選擇:

  1. 捕獲異常並記錄它們。
  2. 捕捉異常和throw new RuntimeException(ex)(重新拋出運行時異常,放置原稿的一個原因)

此外,你需要異常區分。如果您的系統有很多自定義異常,則可能是因爲某個原因而定義的,並且在引發其中一個異常時會發生特定行爲。

+0

「捕獲異常並拋出新的RuntimeException(ex)」,因此您建議用弱類型的系統替換強類型的系統? – rsp 2009-12-02 21:19:02

+0

他似乎願意擺脫所有這些例外。它很大程度上取決於例外情況,程序流程應該如何繼續。 – Bozho 2009-12-02 21:22:14

+0

是的,我正在努力在很多情況下切換到未經檢查的異常(在哪裏有意義)。不幸的是,該系統沒有自定義例外。雖然這並不總是一件壞事,但它必然是在這種情況下。 – JasCav 2009-12-02 21:23:23

2

你的問題的答案是:這取決於。

  • 如果try塊中的代碼是一致的地方是沒有意義的錯誤的情況下進行,第一種方法是最好的
  • 代碼是否採取有相對無關單獨的步驟(解析例如數字),並且可以在不中止該方法的其餘部分的情況下恢復

關於您繼承的代碼的一般註釋;這聽起來像是異常被濫用以傳遞狀態,我會重構,以便在可以處理異常的位置捕獲異常,並引入返回值或屬性來處理狀態。

0

如果try/catch塊沒有添加有用的信息,只要允許該方法拋出異常並在調用者可以明智地對異常做些什麼的情況下處理。這可以顯着減少try/catch的數量(一個數量級)。

順便說一句,重新拋出任何異常的技巧是。

try { 
    // do something 
} catch (Throwable t) { 
    Thread.currentThread().stop(t); // rethrow any exception. 
} 
0

除了已經提出的建議,您可能還想考慮從函數的「肉」中提取try/catch塊。

public void delete(Page page) { 
    try { 
     deletePageAndAllReferences(page); 
    } 
    catch (Exception e) { 
     logError(e); 
    } 
} 

private void deletePageAndAllReferences(Page page) throws Exception { 
    deletePage(page); 
    registry.deleteReference(page.name); 
    configKeys.deleteKey(page.name.makeKey()); 
} 

private void logError(Exception e) { 
    logger.log(e.getMessage()); 
} 

這讓你專注於你真正感興趣的功能,而不需要異常處理。