什么时候应该在Java中使用throws关键字?

时间:2019-05-25 09:04:07

标签: java exception throws

throws关键字仅用于检查的异常。它通过throws关键字指示调用者使用try catch块来排除所有列出的异常。

由于我们知道模块中可能会发生哪种检查异常,因此:

  1. 我们为什么不在模块内部使用try catch块来处理已检查的异常?
  2. 我们可以使用try-catch块处理模块内部的检查异常吗?
  3. 如果(2)的答案为“是”,那么为什么我们可以在模块本身内部排除相同的异常时,为什么要使用throws关键字强制调用者排除那些异常?

那样,每次调用该方法时,我们都不需要手动例外。

4 个答案:

答案 0 :(得分:5)

  1. 所有有关如何从异常中恢复的信息。应该是什么java.lang.File在文件不存在时怎么办?由于不知道哪种方法最适合被呼叫者,因此可以让被呼叫者处理这种情况
  2. 当然,如果明确说明了应如何处理异常,则可以在模块中处理异常。如果处理方式取决于被调用方或上下文,请让调用函数决定
  3. 现在应该清楚

答案 1 :(得分:4)

让我以FileInputStream::new抛出FileNotFoundException为例来澄清您的误解。

例如,我们有如下代码:

FileInputStream fis = new FileInputStream("/some/path/to/file.txt");

那可能会抛出一个FileNotFoundException,而你是在说,

  

FileInputStream显然知道它将要抛出FileNotFoundException,所以为什么它本身不处理?

因为FileInputStream不知道如何处理异常!

根据情况,有许多处理FileNotFoundException的方法:

  • 如果文件路径来自用户输入,则可能要求用户输入另一个文件路径
  • 您可能会显示一条错误消息
  • 您可能什么也不做,只是让它崩溃

根据情况,上述所有选项可能都是完全明智的选择。 FileInputStream将如何了解您的情况?不是!

这就是使用throws子句的原因:

  

我抛出了这些异常,请自行处理。

答案 2 :(得分:1)

有时您想在应用程序的另一部分中管理某些异常。

例如,您可以拥有一个仅将请求发送到互联网并带回响应的软件包。 如果您在无头服务器应用程序和具有用户界面的桌面应用程序中都将此库用作lib,则需要以不同方式管理to例外。对其进行记录并重试无头应用程序,并为台式机应用程序显示错误消息和重试按钮。

如果仅在网络软件包中管理异常,则不会有此情况,如果引发异常,则应用程序的其余部分可以根据需要进行处理。

这里还有其他用例,如果您不知道将如何使用您的软件包(那么您或其他人可以选择以后如何使用它),这可能会很有用

通常的想法是将纯代码逻辑与异常管理分离开。

答案 3 :(得分:1)

请注意,您还可以重新引发异常。在许多情况下,将错误传递给下一层是完全合理的。如果您还向您的方法添加throws IOException,则不必处理它。在许多情况下,处理此类故障的唯一方法是失败,通常应在最外层进行。

IDE将提醒您缺少throws,并提出解决方案。因此,与定义故障行为的好处相比,开发人员的工作量很小。

但是应该清楚的是,IDE不是编译器可以预测未来还是适当的抽象。

首先,接口或抽象方法可以并且应该声明异常。例如:

interface Opener {
    InputStream open(String id) throws IOException;
}

提醒该界面的用户处理此类错误,例如找不到文件异常。

此外,编译器或IDE不知道正确的抽象。您的代码可以执行

if (httpcode == 404)
  throw new FileNotFoundException("Server returned a 404 error.");

但是您还不知道是否以后可以将其更改为其他异常,因为它实际上不是文件。例如,您可能需要一个网络异常的子类。但是,您可以确定要抛出的所有异常都是IOException,因此需要该方法的用户在此级别上对其进行处理。