1
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()它编译。

4

3 回答 3

3

编译器不可能知道它总是Assert.fail()会抛出异常,因此编译器仍然需要一个语句(或Ian Roberts建议的显式语句)。当您显式编码时,编译器肯定知道无法达到方法的关闭并且 a是不需要的。returnthrowthrow new AssertionError()}return

于 2014-04-25T10:27:27.807 回答
3

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

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

您的示例中的“可以正常完成”归结为(第 14.21 节

一个不是 switch 块的非空块可以正常完成,前提是它的最后一条语句可以正常完成。

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

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

[...]

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

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

一个表达式语句可以正常完成,只要它是可达的。

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

同一部分还定义了

, break, continue, returnorthrow语句不能正常完成。

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

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

我个人会尝试一下,并发表评论解释说,如果达到这条线,就会出现非常错误的情况......

于 2014-04-25T10:28:42.650 回答
0

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

于 2014-04-25T10:27:28.977 回答