无限循环中断方法签名而没有编译错误

Sim*_*maa 65 java compilation infinite-loop

我想知道为什么Java中允许以下代码,而不会出现编译错误?在我看来,此代码通过不返回任何内容来中断方法签名String.有人可以解释我在这里缺少的东西吗?

public class Loop {

  private String withoutReturnStatement() {
    while(true) {}
  }

  public static void main(String[] a) {
    new Loop().withoutReturnStatement();
  }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 83

}方法的最后一个是无法访问的 - 如果可以在不返回值的情况下到达方法的末尾,则只会出现编译错误.

这对于由于异常导致方法结束无法访问的情况更有用,例如

private String find(int minLength) {
    for (String string : strings) {
        if (string.length() >= minLength) {
            return string;
        }
    }
    throw new SomeExceptionIndicatingTheProblem("...");
}
Run Code Online (Sandbox Code Playgroud)

这个规则在JLS第8.4.7节中:

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

您的方法无法正常完成,因此没有错误.重要的是,它不仅不能正常完成,而且规范认识到它无法正常完成.来自JLS 14.21:

一个while语句可以正常完成且仅当以下至少有一个为真:

  • while语句是可到达和条件表达式不是常量表达式(§15.28)与值true.
  • break退出while语句时有一个可到达的语句.

在您的情况下,条件表达式一个带值的常量true,并且没有任何break语句(可达或其他),因此while语句无法正常完成.

  • @PaulDraper:不,编译器可以*不*选择更复杂.语言规范非常清楚可达性."如果至少满足下列条件之一,则while语句可以正常完成:while语句可以访问,条件表达式不是常量表达式(第15.28节),值为true.[...]".`"foo".length()> 0`不是常量表达式.Java并没有试图解决暂停问题 - 它只是定义了编译器必须遵守的一些明确的规则,这些规则解决了在编译时确定结果的非常少的情况. (4认同)

Ruc*_*era 22

 private String withoutReturnStatement() {
    while(true) {
        // you will never come out from this loop
     } // so there will be no return value needed
    // never reach here ===> compiler not expecting a return value
  }  
Run Code Online (Sandbox Code Playgroud)

为了更加澄清,试试这个

private String withoutReturnStatement() {
    while(true) {}
    return ""; // unreachable
}
Run Code Online (Sandbox Code Playgroud)

它说unreachable声明

  • +1的答案第二部分.这非常清楚. (3认同)