"Method must return a result"调用另一个仅引发异常的方法时


boolean method(int value) {
    switch(value) {
    case 0:
        return false;
    case 1:
        return true;
    default:
        Assert.fail("Unhandled value.");
    }
}

这会导致编译失败,并返回错误"Method must return a result",即使Assert.fail()只抛出AssertionError。如果我自己抛出一个AssertionError而不是调用Assert.fail(),它就会编译。

编译器无法知道Assert.fail总是抛出异常,除非它深入研究该方法的字节码并对其进行某种静态分析(一旦你开始了这种事情,你该在哪里停止?(。Java语言规范规定(第8.4.7节(

如果一个方法被声明为具有返回类型,那么如果该方法的主体能够正常完成,则会发生编译时错误(§14.1(

在你的例子中,"可以正常完成"可以归结为(第14.21节(

非开关块的非空块可以正常完成,如果其中的最后一条语句可以正常完成。

方法中的最后一个语句是switch语句:

switch语句可以正常完成,如果以下至少一项为真:

[…]

  • 开关块中的最后一条语句可以正常完成

switch中的最后一条语句是表达式语句(方法调用(

表达式语句可以正常完成,前提是它是可访问的。

即,规范特别指出编译器不应查看任何方法调用内部,并且任何方法调用表达式都必须被视为可以正常完成的表达式。

同一节还定义了

breakcontinuereturnthrow语句无法正常完成。

因此,为了让编译器满意,您需要在方法的末尾添加一个return或throw

// will never be reached
throw new Error();

我个人会投一投,并评论解释说,如果达到这条线,就会出现严重问题。。。

编译器不可能知道Assert.fail()总是抛出异常,因此编译器仍然需要return语句(或Ian Roberts建议的显式throw(。当显式地对throw new AssertionError()进行编码时,编译器肯定知道无法达到方法的结束},并且不需要return

对于所有代码路径,必须始终有一个返回值或一个异常。编译不知道Assert.fail并不总是抛出异常

最新更新