簡體   English   中英

處理方法中的多個異常

[英]Handling Multiple Exceptions within a Method

我目前正致力於維護一段有點“異常快樂”的代碼。 基本上,任何方法或任何東西拋出異常。 我將努力解決這個問題,但與此同時,我想知道在較小的代碼塊中處理個別異常的最佳方法是什么,例如方法。 做這樣的事情更好:

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.
  }
}

我意識到這是一個非常基本的問題,但是在查看了數百種帶有異常的方法之后,我開始想知道如何最好地處理所有這些方法以及最佳實踐可能在這里。

首先,您應該只將代碼放在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
}

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

  • 如果try塊中的代碼是連貫的,在發生錯誤的情況下繼續進行是沒有意義的,那么第一種方法是最好的
  • 如果代碼采取相對不相關的單獨步驟(例如解析數字)並且可以在不中止方法的其余部分的情況下恢復,那么秒數appraoch是有意義的

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

你的bMethod不是很有用的插圖。 嘗試重新編寫它。 無論如何,你有兩個選擇:

  1. 捕獲異常並記錄它們。
  2. 捕獲異常並throw new RuntimeException(ex) (重新拋出運行時異常,將原始設置為原因)

此外,您還需要區分異常。 如果您的系統有許多自定義異常,則可能是出於某種原因定義了它們,並且在拋出其中一個異常時會出現特定的行為。

如果try / catch塊沒有添加有用的信息,只需允許該方法拋出異常並將其處理到調用者可以明白地執行異常操作的地方。 這可以顯着減少嘗試/捕獲的數量(按一個數量級)。

BTW重新拋出任何異常的技巧是。

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

除了已經提出的建議之外,您可能還需要考慮從函數的“肉”中提取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());
}

這使您可以將注意力集中在您真正感興趣的功能上,而不會遇到異常處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM