java - java try block 的范围是否应该尽可能紧密?

标签 java exception-handling readability

有人告诉我,使用 Java 的 try-catch 机制会产生一些开销。因此,虽然有必要将抛出已检查异常的方法放在 try block 中以处理可能的异常,但从性能角度来看,最好将 try block 的大小限制为仅包含可能抛出异常的那些操作。

我不太确定这是一个合理的结论。

考虑以下两个处理指定文本文件的函数的实现。

即使第一个确实会产生一些不必要的开销,我发现它更容易理解。仅通过查看语句就不太清楚异常究竟来自何处,但评论清楚地表明了哪些语句是负责任的。

第二个比第一个更长更复杂。特别是,第一个很好的读行习惯必须被破坏以使 readLine 调用适合 try block 。

在定义中可能引发多个异常的函数中处理异常的最佳做法是什么?

这个包含try block 内的所有处理代码:

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 block 中抛出异常的方法:

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 block 的大小对性能没有影响。性能会受到运行时实际引发异常的影响,这与 try block 的大小无关。

但是,保持较小的 try block 可以产生更好的程序。

您可能会捕获异常以恢复和继续,或者您可能会捕获它们只是为了将它们报告给调用者(或通过某些 UI 向人类报告)。

在第一种情况下,您可以从中恢复的故障通常非常具体,这会导致较小的 try block 。

在第二种情况下,一个异常被捕获,以便它可以被另一个异常包装并重新抛出,或显示给用户,小的 try block 意味着您可以更准确地知道哪个操作失败,以及进行该调用的更高级别的上下文。这允许您创建更具体的错误报告。

当然,这些指南有……异常(exception)(抱歉!)。例如,在某些情况下,非常具体的错误报告可能是一个安全问题。


了解 try block 对编译代码的影响可能很有用。它根本不会改变编译的指令! (当然,相应的 catch block 可以,因为它与任何其他代码一样。)

try block 在与方法关联的异常表中创建一个条目。该表具有一系列源指令计数器、异常类型和目标指令。当引发异常时,将检查此表以查看是否存在具有匹配类型的条目,以及包含引发异常的指令的范围。如果是,则执行分支到相应的目标编号。

要意识到的重要一点是,除非需要,否则不会查询此表(并且对运行性能没有影响)。 (忽略加载类的一点开销。)

关于java - java try block 的范围是否应该尽可能紧密?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2633834/

相关文章:

java - 从侧面包中抛出异常是否正确?

java - org.openqa.selenium.ElementNotVisibleException : Element is not currently visible while clicking a checkbox through SeleniumWebDriver and Java

java - 使用htmlunit获取HTML页面

java - AdMob 覆盖了我的 EditText 和 TextView

javascript - 处理 Protractor 中的未知错误

javascript - 使大数字在 JavaScript 中可读

Java Eclipse 在运行时连续获取命令行参数

spring - Spring中过滤器的异常处理

c++ - 你能在 VS 2008 中用 C++ 创建可折叠的 #Region 之类的范围吗?