@Contract和抛出异常

时间:2014-02-07 18:24:06

标签: java intellij-idea

如果我有一些简单的代码:

public int doSomething(final String str)
{
  try
  {
    return Integer.parseInt(str);
  }
  catch (final NumberFormatException e)
  {
    throw new IllegalArgumentException("Bad");
  }
}

一切都很好,但如果我想创建异常并将其移动到它自己的方法:

public int doSomethingElse(final String str)
{
try
  {
    return Integer.parseInt(str);
  }
  catch (final NumberFormatException e)
  {
    doThrow();
  }
}

public void doThrow()
{
  throw new IllegalArgumentException("Bad");
}

然后代码不再在IntelliJ中编译,因为它不理解doThrow()将始终抛出异常,因此抱怨在该路径中没有返回值。

在我看来,这是为IntelliJ合约设置的类型,但如果我尝试将@Contract("_ -> fail")注释添加到doThrow(),则无效。如何才能完成这项工作(在调用return null之后添加doThrow(),这很难看。

1 个答案:

答案 0 :(得分:2)

Java编译器不知道像@Contract这样的JetBrains属性。 IntelliJ可能知道doThrow()总是抛出,但编译器没有抛出,所以这不是格式良好的代码。

在这种情况下,我使用了一种实用方法:

public final class ContractUtilities {
    public static IllegalStateException unreachable() {
        return new IllegalStateException("Code is supposed to be unreachable.");
    }
    // ...
}

...我添加一个理论上无法访问的throw语句,如下所示:

public int doSomethingElse(final String str) {
    try {
        return Integer.parseInt(str);
    }
    catch (final NumberFormatException e) {
        doThrow();
        throw ContractUtilities.unreachable();
    }
}

您也可以简单地让doThrow()返回要抛出的异常:

public int doSomethingElse(final String str) {
    try {
        return Integer.parseInt(str);
    }
    catch (final NumberFormatException e) {
        throw doThrow();
    }
}