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()
,则会编译。
答案 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
中的最后一个语句是表达式语句(方法调用)
如果表达式语句可以访问,则表达式语句可以正常完成。
即。规范明确指出编译器不应该查看任何方法调用,并且任何方法调用表达式必须被认为是可以正常完成的那个。
同一部分也定义了
break
,continue
,return
或throw
声明无法正常完成。
因此,为了让编译器满意,您需要添加一个返回或抛出到方法的末尾
// will never be reached
throw new Error();
我个人会去投票,并发表评论说明如果达到这条线就会出现问题......
答案 2 :(得分:0)
您必须始终拥有所有代码路径的返回值或例外。编译不知道Assert.fail并不总是抛出异常