"方法必须返回结果"当调用另一个只抛出异常的方法时

时间:2014-04-25 10:24:48

标签: java methods assert assertions throws

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

编译错误"方法必须返回结果"即使Assert.fail()除了抛出AssertionError之外什么都不做。如果我自己抛出AssertionError而不是调用Assert.fail(),则会编译。

3 个答案:

答案 0 :(得分:3)

编译器不可能知道Assert.fail()始终抛出异常,因此编译器仍需要return语句(或显式throw正如Ian Roberts所建议的那样。当您显式编码throw new AssertionError()时,编译器确定无法达到方法的结束}并且不需要return

答案 1 :(得分:3)

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

  

如果声明方法具有返回类型,则如果方法的主体可以正常完成(第14.1节),则会发生编译时错误。

在您的示例中,“可以正常完成”归结为(section 14.21

  

非空交换块的非空块可以正常完成,如果其中的最后一个语句可以正常完成。

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

  

如果至少满足下列条件之一,则switch语句可以正常完成:

     

[...]

     
      
  • 交换机块中的最后一个语句可以正常完成。
  •   

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

  

如果表达式语句可以访问,则表达式语句可以正常完成。

即。规范明确指出编译器不应该查看任何方法调用,并且任何方法调用表达式必须被认为是可以正常完成的那个。

同一部分也定义了

  

breakcontinuereturnthrow声明无法正常完成。

因此,为了让编译器满意,您需要添加一个返回或抛出到方法的末尾

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

我个人会去投票,并发表评论说明如果达到这条线就会出现问题......

答案 2 :(得分:0)

您必须始终拥有所有代码路径的返回值或例外。编译不知道Assert.fail并不总是抛出异常