【发布时间】:2014-07-30 14:10:43
【问题描述】:
我正在用 java 做一些小程序。我知道如果我写 while(true); 程序将冻结在这个循环中。如果代码是这样的:
测试 1:
public class While {
public static void main(String[] args) {
System.out.println("start");
while (true);
System.out.println("end");
}
}
编译器向我抛出错误:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Unreachable code
at While.main(While.java:6)
我不知道存在这个错误。但我知道为什么它会被抛出。当然,第 6 行无法访问,导致编译问题。然后我测试了这个:
测试 2:
public class While {
public static void main(String[] args) {
System.out.println("start");
a();
b();
}
static void a() {
while(true);
}
static void b() {
System.out.println("end");
}
}
由于某种原因程序正常运行(控制台打印“开始”然后冻结)。编译器无法检查 void a() 内部并发现它无法访问。可以肯定的是我试过了:
测试 3:
public class While {
public static void main(String[] args) {
System.out.println("start");
a();
System.out.println("end");
}
static void a() {
while(true);
}
}
结果与测试 2 相同。
经过一番研究,我发现了这个question。 因此,如果括号内的代码是变量,编译器不会抛出异常。这是有道理的,但我认为这不适用于 voids。
问: 那么,如果 void b()(测试 2)和 System.out.println("end");(测试 3)无法访问?
编辑:我在 C++ 中尝试了测试 1:
#include <iostream>
using namespace std;
int main()
{
cout << "start" << endl;
while(true);
cout << "end" << endl;
return 0;
}
编译器没有抛出任何错误,然后我得到了与测试 2 和测试 3 相同的结果。所以我想这是 java 的东西?
【问题讨论】:
-
Java 编译器不会“查看”其他方法,因为它对可达/不可达代码进行 原始 静态分析。 (这样做会给虚拟方法/多态性和单独的编译单元带来许多复杂性。)
-
问得很好。
-
@user2864740 是正确的。在整个程序中寻找可访问/不可访问的代码相当于解决停机问题(如果有记忆的话),所以它不能像大多数人想要的那样完成。
-
@user3580294 在整个程序中提供完整且完全准确的可达性分析将等同于解决停机问题。然而,有很多方法可以查看并返回不完整但有用的结果,使用更高级的启发式。 (一般来说,每当 任何人 说给定的编译器任务等同于解决停机问题时,他们就错了。“停机问题”应该是您的即时“否”触发短语之一.)
-
@Leushenko 好吧,我有点含糊其辞,但我不认为我说过这是一项不可能完成的任务。我只是说“它不能像大多数人想要的那样完成”,这为编译器留下了足够的空间来获取一些信息。感谢您的澄清,尤其是斜体部分。
标签: java c++ compiler-construction while-loop