Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java能识别无限循环吗?_Java_Loops_While Loop - Fatal编程技术网

Java能识别无限循环吗?

Java能识别无限循环吗?,java,loops,while-loop,Java,Loops,While Loop,给定以下代码示例: public class WeirdStuff { public static int doSomething() { while(true); } public static void main(String[] args) { doSomething(); } } 这是一个有效的Java程序,尽管doSomething()方法应该返回int,但永远不会返回int。如果运行它,它将以无限循环结束。如果将w

给定以下代码示例:

public class WeirdStuff {

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

    public static void main(String[] args) {
        doSomething();
    }
}
这是一个有效的Java程序,尽管doSomething()方法应该返回int,但永远不会返回int。如果运行它,它将以无限循环结束。如果将while循环的参数放在单独的变量中(例如boolean bool=true),编译器将告诉您在此方法中返回int


所以我的问题是:这是Java规范中的某个地方吗?这种行为是否有用?

如果你问无限循环是否有用,答案是肯定的。在很多情况下,您希望某些东西永远运行,尽管循环通常会在某个点终止

至于你的问题:“java能识别什么时候循环是无限的吗?”答案是计算机不可能有一个算法来确定一个程序是否会永远运行。了解:

再读一点,您的问题还在于问为什么doSomething()函数不抱怨它没有返回int

有趣的是,下面的源代码没有编译

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


   }
  }  
  public static void main(String[] args) {               
   doSomething();    
  }
}
这向我表明,正如关于停止问题的wiki页面所表明的,不可能有一个算法来确定每个问题是否会终止,但这并不意味着有人没有添加简单的案例:

while(true);
我上面的例子稍微复杂一些,所以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();    
  }
}

以上是有效的,所以while(正确);不会被编译器忽略为不可访问,否则会抛出编译时错误

是的,您可以在某些线程中看到这些“无限”循环,例如在某个端口上侦听传入消息的服务器线程。

重新阅读问题后

Java理解while(true);无法实际完成,它无法完全跟踪以下代码

boolean moo = true;
while (moo);

这有用吗?值得怀疑。

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

所以我的问题是:这是Java规范中的某个地方吗

根据规范,该程序是合法的Java。JLS(和Java编译器)认识到该方法无法返回,因此不需要
return
语句。事实上,如果在循环后添加
return
语句,Java编译器会给您一个编译错误,因为return语句将是无法访问的代码

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();    
  }
}
在某些情况下,这种行为可能有用吗

我不这么认为,除了在晦涩难懂的单元测试中


我偶尔会写一些永远不会返回的方法(通常),但将当前线程放入一个不间断的无限繁忙循环中几乎没有任何意义。

您可能正在实现一个通用接口,这样,即使该方法可能以有意义的返回值退出,您的特定实现也是一个有用的无限循环(例如,一个网络服务器),它从来没有应该退出的情况,即触发返回值意味着什么的操作

另外,对于像
booleanx=true;while(x);
这样的代码,如果
x
上有一个
final
修饰符,这将编译。我现在不知道,但我可以想象这是Java选择的合理的简单常量表达式分析(这需要直接定义,因为由于对依赖于它的程序的拒绝,它是语言定义的一部分)。

我将仅引用,因为这一点相当清楚:

本节致力于对“可达”一词的精确解释其思想是,从包含语句的构造函数、方法、实例初始值设定项或静态初始值设定项的开头到语句本身,必须有一些可能的执行路径。分析考虑语句的结构。除了对while、do和条件为如果表达式的常量值为true
,则在流分析中不考虑表达式的值

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

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

如果S前面的语句可以正常完成,则非空块(不是开关块)中的其他语句S都是可访问的

然后将上述定义应用于:

如果一个方法被声明为具有返回类型,那么它的主体中的每个返回语句(§14.17)都必须有一个表达式。如果该方法的主体可以正常完成(§14.1),则会发生编译时错误

换句话说,具有返回类型的方法必须仅通过使用提供值返回的return语句返回;不允许“从其主体的末尾删除”

请注意,方法可以声明