声明方法是否会抛出未经检查的异常是否有优势?

时间:2014-07-03 12:44:34

标签: java exception unchecked-exception

如果我有一个抛出未经检查的异常的方法,例如:

void doSomething(int i) {
  if (i < 0) throw new IllegalArgumentException("Too small");
  // ...
}

明确声明该方法抛出异常,即

是否有任何好处
void doSomething(int i) throws IllegalArgumentException {
  if (i < 0) throw new IllegalArgumentException("Too small");
  // ...
}

与描述javadoc中的行为(或除此之外)相反:

/**
 * This method does something useful.
 * @param i some input value
 * @throws IllegalArgumentException if {@code i < 0}
 */
void doSomething(int i) {
  if (i < 0) throw new IllegalArgumentException("Too small");
  // ...
}

我声称拥有throws的原因是没有用的:

  • throws不提供有关抛出异常的情况的信息,只提供可能抛出的内容;
  • 因为它是一个未经检查的异常,所以我不会在调用代码时强制处理异常。如果我去查看doSomething;
  • 的实施情况,我只会真的知道它可能会被抛出
  • doSomething的主体可能会调用抛出其他类型未经检查的异常的代码;声称这种方法会引发IllegalArgumentException&#39;似乎它只是讲述故事的一部分,可能;
  • 如果方法是非final的,则可以重写它,以便声明新的实现抛出额外的未经检查的异常;你不知道你正在调用哪种实现。

我声称拥有throws的原因是有用的:

  • 报告您在调用方法时可能会遇到的问题。

简而言之,我认为throws是不必要的,但通过@throws的javadoc描述很有用。我有兴趣了解其他人&#39;对此的看法。

3 个答案:

答案 0 :(得分:6)

如果您的API用户看不到您的源代码,他将看不到javadoc评论。这就是为什么声明throws子句可能有用。

一些程序员更容易从方法签名中快速确定异常,而不是查看javadoc中的内容。

但总的来说,我认为仅在javadocs中列出未经检查的异常更有用,因为如果throws子句中存在已检查和未检查的异常,则情况可能会令人困惑。没有编译器或没有查看每个异常类签名,您无法确定异常的类型。

然而,未经检查的异常意味着情况至关重要,并且程序无法在运行时修复。如果你通过检查异常的目的使用未经检查的异常(你假设情况可以修复)但由于某种原因你不希望编译器强制捕获异常,那么我建议把异常放在throws子句中。

答案 1 :(得分:5)

当您声明方法throws是您对调用者说的异常时:

您有两种选择:

  1. 将自己视为抛出相同的异常。
  2. 抓住异常并处理它。
  3. 在案例1中,它可能会提醒用户实施finally - 这可能是奖金。

    在案例2中,它将注意力集中在例外上,这也可能是一种奖励。

    如果您隐藏了这种可能性,则上述提醒都不会发生在用户身上。

    对我来说,一个人可能会不必要地混乱他们的代码而另一个人保持甜蜜和简单。然而,一个人鼓励关注潜在的问题而另一个人可能会让你感到幸福无知。

    底线 - 问问自己将异常声明为抛出是多么令人恼火(例如,你应该声明throws NullPointerException吗? - 不!)并且这种烦恼是由于用户关注{{{{ 1}},catchfinally

答案 2 :(得分:0)

例外用于报告3种问题:

  • JVM和低级运行时环境的问题。
  • 检测到逻辑错误(错误)。
  • 程序员在尝试操作前无法预测的运行时问题。

前两种可能随时发生,基本上没有好办法处理它们。所以抓住它们是没有意义的,因此通过在throws条款中声明它们来记录它们没有意义。第三种是您希望客户了解和处理的那种。对于那些,您希望清楚地记录可能抛出异常,暗示调用代码必须准备好通过捕获它或正确传播它来处理异常。您可以使用throws子句来执行此操作。

现在,对我而言,似乎很清楚Java语言设计者打算检查异常,并且只检查异常,以用于第三种类型。如果总是这样,那么问题的简单答案就是,不,不要在throws子句中声明未经检查的例外。

但是有一个并发症。它是now quite common(由Spring推广)以避免第三种类型的已检查异常,并且几乎在所有情况下都使用未经检查的异常。如果您使用该样式进行编程,则使用throws子句声明未经检查的异常可能会有所帮助。