【问题标题】:How to correctly catch an exception if method uses method that throws an exception如果方法使用引发异常的方法,如何正确捕获异常
【发布时间】:2019-10-01 17:20:06
【问题描述】:

我有一个关于在使用另一种可能引发异常的方法的方法中捕获异常的问题。

public void methodA(File file) {
  try {
  }
  catch (IOException ex) {
  }
}

public void methodB() {
 // do something with the file
 File file = new File("/example.txt");
 methodA(file);
}

我需要在 methodB 中创建一个 try 和 catch 块吗?或者在methodA内部捕获IOException这种情况下的异常就足够了?

【问题讨论】:

  • methodA 不会抛出任何异常,因此methodB 没有什么可以捕获的。
  • 我不知道哪个方法实际上正在做一些会从上面的代码中引发 IOException 的事情。基本上,规则是:低级方法应该声明它们抛出异常而不是试图捕获它们。在最高级别处理异常。所以如果a调用b调用cc做了一些可能引发异常的事情,不要在cb处理它(通常),在a处理它。
  • 您可以在methodA 中做任何事情,但您希望methodB 继续,即使methodA 发生了异常?如果不是,你可能不应该处理methodA中的IOException,而是声明它抛出一个异常并在methodB中通过类似的逻辑处理它,如果你不能处理methodB中的异常,则声明它抛出。跨度>

标签: java


【解决方案1】:

这取决于您想要实现的目标。

在您的代码示例中,methodA 将处理异常并继续执行 methodB 而不会中断。这可能不是您想要的,因为读取文件时出错,应该妥善处理。

您很可能希望在执行链中冒泡您的异常并在相关对象中处理它(例如,一些可以向用户输出错误消息的错误处理程序)。

像这样冒泡你的异常:

public void methodA(File file) throws CustomUserInputException {
  try {
  }
  catch (IOException ex) {
    throw new CustomUserInputException(ex, "Error opening file" + file.getPath());
  }
}

然后在适当的对象中处理它,如下所示:

public void methodB() {
 // do something with the file
 File file = new File("/example.txt");
 try {
   methodA(file);
  }
  catch (CustomUserInputException ex) {
    showErrorToAnUser();
    stopStandardProgramExecution();
  }
}

【讨论】:

    【解决方案2】:

    不,在这种情况下,您不需要在 methodB 中使用 - 但您可能想要这样做,因为 methodA 可能会抛出 IOException 之外的其他错误。

    这取决于您的意图和异常的类型 - 如果您的方法 A 抛出已检查的异常,方法 B 必须捕获它或声明它抛出该异常。如果它是一个 RuntimeException,methodB 可能会捕获它或忽略它。 在大多数技术栈中,检查异常很少见,大多数人认为它们是失败的实验。

    最后,方法是否需要捕获异常取决于 - 可以想象方法 B 可以处理错误吗?如果是这样,抓住它 - 如果不是,让它冒泡,例如到一般的错误处理程序,甚至使程序崩溃。没有什么比捕获每个错误并做错事的程序更烦人的了。

    【讨论】:

      【解决方案3】:

      你不能,因为异常只能向上移动调用堆栈。如果程序在异常之后还运行方法,那么首先创建异常有什么意义?

      尝试处理发生的异常。如果在创建File 时有可能出现异常,则应该在创建文件的地方进行处理。否则,确保传入值不是异常的开销会太高。

      我建议要么在 methodB 中捕获它,要么将文件名传递给 methodA 并让它创建 File 并捕获任何异常。

      【讨论】:

      • "尝试处理异常发生的地方。"这是不正确的。您希望处理可以以有意义的方式实际处理的异常。这不一定发生在哪里。
      • 我认为不应将异常送去处理。如果一个异常需要在 multi-catch 之外进行额外的解析/处理,那么您可能不应该使用异常。
      • 问题不在于捕获,问题在于您在捕获中做什么。一个简单的log.e(exception) 对于小型 CLI 工具就足够了,但对于真正的应用程序却不是。
      • 我认为这超出了这个问题的范围。我并不是在提倡极简主义的捕获,而是评论如何对异常进行额外处理开始接近流控制。例如,提示用户从IOExcepton 重新选择输入文件,而不是将问题通过管道传输到代码库的另一部分。 stackoverflow.com/questions/729379/…
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-19
      • 2011-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多