Java 不认为 fail 方法是分支的结束



我有一个类Game,它有一个具有以下签名的构造函数:

public Game(String[] boardState) throws InvalidStringsInputException, WrongNumberOfMarksException

junit4测试用例中有一种方法:

public static Game newGameFromStringsSuccessful(String[] input) //it is the line 9
{
    try
    {
        return new Game(input);
    }
    catch (WrongNumberOfMarksException exception)
    {
        fail("Caught exception where it shouldn't be");
    }
    catch (InvalidStringsInputException exception)
    {
        fail("Caught exception where it shouldn't be");
    }
}

我正在使用eclipse,它显示了一个错误:This method must return a result of type Game line 9 Java Problem

如果我在两个catch块的末尾都插入return null,错误就会消失,但我的问题不是:为什么java即使在调用fail()方法后也想要它?

为什么java在调用fail()方法之后仍然需要它?

因为编译器不知道fail不能正常返回。在Java中无法表达这一点。fail消息调用的末尾仍然可访问,因此方法的末尾也是可访问的。

假设fail方法中有一个错误,所以你最终到达了方法的末尾——你预计会发生什么?

对此,最简单的修复方法是在方法末尾抛出一些运行时异常,例如AssertionError:

throw new AssertionError("fail must have returned normally!");

说"世界太疯狂了,我不想再住在这里了"基本上是个例外——这也让编译器感到高兴,因为该方法的右大括号不再可用。

另一种替代方案(此处不可用,因为您无法控制fail方法)是声明fail方法以返回某种运行时异常,此时您的catch块可能如下所示:

catch (InvalidStringsInputException exception)
{
    throw fail("Caught exception where it shouldn't be");
}

当然,fail实现仍然是抛出异常而不是返回异常,但这意味着编译器知道捕获块肯定不会正常完成。

下面Jon的回答解释了编译器抱怨的原因。然而,我建议避免这种情况的正确方法是在测试中不要使用try/catch。只需让异常在调用堆栈中向上传播并退出测试即可。JUnit将捕获它并使测试失败,同时提供抛出异常的整个堆栈跟踪。

或者,如果您不想传播throws子句,请将异常包装在RuntimeException中,然后抛出它。同样,这将提供堆栈跟踪,以便进行更好的诊断。

最新更新