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语句返回;不允许“从其主体的末尾删除”
请注意,方法可以声明