Java是否识别无限循环?

lei*_*ifg 25 java loops while-loop

给出以下代码示例:

public class WeirdStuff {

    public static int doSomething() {
        while(true);
    }

    public static void main(String[] args) {
        doSomething();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个有效的Java程序,虽然方法doSomething()应该返回一个int但从来没有.如果你运行它,它将以无限循环结束.如果将while循环的参数放在一个单独的变量中(例如boolean bool = true),编译器会告诉你在这个方法中返回一个int.

所以我的问题是:这是Java规范中的某个地方,是否存在这种行为可能有用的情况?

Pav*_*aev 19

我将引用Java语言规范,因为它非常清楚:

本节致力于对"可达"一词的精确解释.我们的想法是,从构造函数,方法,实例初始化程序或包含语句本身的静态初始化程序开始,必须有一些可能的执行路径.分析考虑了陈述的结构.除了对while,do和for条件表达式具有常量值true的语句特殊处理外,在流分析中不考虑表达式的值.

...

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

  • while语句是可访问的,条件表达式不是值为true的常量表达式.
  • 有一个可到达的break语句退出while语句.

...

如果S之前的语句可以正常完成,则非空块中的非交换块中的每个其他语句S都是可到达的.

然后将以上定义应用于:

如果声明方法具有返回类型,则其主体中的每个return语句(第14.17节)都必须具有表达式.如果方法的主体可以正常完成,则会发生编译时错误(第14.1节).

换句话说,具有返回类型的方法必须仅使用提供值返回的return语句返回; 不允许"从身体的末端掉下来".

请注意,方法可能具有声明的返回类型,但不包含return语句.这是一个例子:

class DizzyDean {
  int pitch() { throw new RuntimeException("90 mph?!"); }
}
Run Code Online (Sandbox Code Playgroud)


Meh*_*ari 13

Java规范定义了一个名为Unreachable statements的概念.您不允许在代码中包含无法访问的语句(这是编译时错误).根据while(true);定义,语句使以下语句无法访问.甚至不允许在Java return语句之后使用while(true);语句.请注意,虽然在一般情况下Halting问题是不可判定的,但是Unreachable Statement的定义比仅停止更严格.它正在决定一个程序肯定不会停止的非常具体的情况.理论上,编译器无法检测所有无限循环和无法访问的语句,但它必须检测规范中定义的特定情况.

  • `while(true)`不可达(显然!).任何跟随`while(true)`的语句都是无法访问的. (3认同)
  • @fastcodejava:实际上,如果循环之后的语句被认为不可达(例如,如果它是`bool x = true; while(x);`),编译器会考虑退出循环可能的"代码路径"并且要求你在那里写一个`return`语句.否则,没有**`return`就不会编译**. (2认同)

Ale*_*lex 7

如果你问无限循环是否有用,答案是肯定的.在很多情况下你想要一些永远运行的东西,尽管循环通常会在某个时候终止.

关于你的问题:"当循环无限时,java可以被识别吗?" 答案是计算机不可能有一个算法来确定程序是否会永远运行.阅读:暂停问题

再读一遍,你的问题也在问为什么doSomething()函数不会抱怨它没有返回int.

有趣的是,以下来源不编译.

public class test {
  public static int doSomething() {                
   //while(true);
   boolean test=true;
   while(test){


   }
  }  
  public static void main(String[] args) {               
   doSomething();    
  }
}
Run Code Online (Sandbox Code Playgroud)

这向我表明,正如停止问题的维基页面所暗示的那样,不可能有一个算法来确定每个问题是否会终止,但这并不意味着有人没有添加简单的案例:

while(true);
Run Code Online (Sandbox Code Playgroud)

到java规范.我上面的例子有点复杂,所以Java不能把它记住为无限循环.确实,这是一个奇怪的边缘情况,但它只是为了使事情编译.也许有人会尝试其他组合.

编辑:不是无法访问代码的问题.

import java.util.*;

public class test {
  public static int doSomething() {                
   //while(true);
   while(true){
    System.out.println("Hello"); 
   }
  }  
  public static void main(String[] args) {               
   doSomething();    
  }
}
Run Code Online (Sandbox Code Playgroud)

以上作品,所以一会儿(真实); 编译器不会被忽略为无法访问,否则会抛出编译时错误!

  • 你的回答是误导性的.计算机程序不可能识别任意程序是否停止,但检查"特定程序"是否停止绝对不是不可能的.当然,编译器可以检查`while(true);`没有`break`或`goto`语句是无限循环这一事实. (2认同)