一千萬個為什麽

搜索

java try塊應該盡可能緊密地限定範圍嗎?

我被告知使用Java try-catch機制會有一些開銷。因此,雖然有必要在try塊中放置拋出checked異常的方法來處理可能的異常,但是在性能方面優先考慮限制try塊的大小以僅包含那些可能拋出異常的操作。

我不太確定這是一個明智的結論。

考慮以下兩個實現處理指定文本文件的函數。

即使第一個確實存在一些不必要的開銷,我發現它更容易理解。通過查看語句來確定異常的確切位置尚不清楚,但評論清楚地表明了哪些陳述是負責任的。

第二個比第一個更長更復雜。特別是,第一個很好的讀取線條必須被修改以適應 readLine 調用到try塊中。

在函數中處理異常的最佳實踐是什麽?在定義中可能拋出多個異常?

這個包含try塊中的所有處理代碼:

void processFile(File f)
{
  try
  {
   //construction of FileReader can throw FileNotFoundException
    BufferedReader in = new BufferedReader(new FileReader(f));

   //call of readLine can throw IOException
    String line;
    while ((line = in.readLine()) != null)
    {
      process(line);
    }
  }
  catch (FileNotFoundException ex)
  {
    handle(ex);
  }
  catch (IOException ex)
  {
    handle(ex);
  }
}

這個只包含在try塊中拋出異常的方法:

void processFile(File f)
{
  FileReader reader;
  try
  {
    reader = new FileReader(f);
  }
  catch (FileNotFoundException ex)
  {
    handle(ex);
    return;
  }

  BufferedReader in = new BufferedReader(reader);

  String line;
  while (true)
  {
    try
    {
      line = in.readLine();
    }
    catch (IOException ex)
    {
      handle(ex);
      break;
    }

    if (line == null)
    {
      break;
    }

    process(line);
  }
}

最佳答案

這裏的基本前提是 false: try 塊的大小對性能沒有影響。性能受到在運行時實際引發異常的影響,並且與 try 塊的大小無關。

但是,保持較小的試塊可以帶來更好的程序。

您可能會捕獲恢復和繼續的異常,或者您可能只是將它們報告給調用者(或通過某些UI向人類報告)。

在第一種情況下,您可以從中恢復的故障通常非常具體,這會導致較小的 try 塊。

在第二種情況下,捕獲異常以便它可以被另一個異常包裝並重新拋出或顯示給用戶,小 try 塊表示您更準確地知道哪個操作失敗,以及進行該調用的更高級別的上下文。這允許您創建更具體的錯誤報告。

Of course, there are… exceptions (sorry!) to these guidelines. For example, in some cases very specific error reports could be a security problem.


了解 try 塊對編譯代碼的影響可能很有用。它根本不會改變編譯指令! (當然,相應的 catch 塊也可以,因為它就像任何其他代碼一樣。)

try 塊在與該方法關聯的異常表中創建一個條目。該表具有一系列源指令計數器,異常類型和目標指令。引發異常時,將檢查此表以查看是否存在具有匹配類型的條目,以及包含引發異常的指令的範圍。如果是,則執行分支到相應的目標號碼。

要意識到的重要一點是,除非需要,否則不會查詢此表(並且對運行性能沒有影響)。 (忽略了加載課程的一點開銷。)

轉載註明原文: java try塊應該盡可能緊密地限定範圍嗎?