问题
在Java中查看以下infinitewhileloop。它会导致它下面的语句出现编译时错误。
while(true) {
System.out.println("inside while");
}
System.out.println("while terminated"); //Unreachable statement - compiler-error.
以下相同的infinitewhile循环,但工作正常,并没有发出任何错误,我只是用一个布尔变量替换条件。
boolean b=true;
while(b) {
System.out.println("inside while");
}
System.out.println("while terminated"); //No error here.
在第二种情况下,循环之后的语句显然无法访问,因为布尔变量b仍为true,编译器根本不会抱怨。为什么?
**编辑:**以下版本的whilegets陷入了无限循环,但是对于它下面的语句没有发出编译错误,即使循环中的if条件总是false因此,循环永远不会返回并且可以由编译器在编译时确定 - 时间本身。
while(true) {
if(false) {
break;
}
System.out.println("inside while");
}
System.out.println("while terminated"); //No error here.
while(true) {
if(false) { //if true then also
return; //Replacing return with break fixes the following error.
}
System.out.println("inside while");
}
System.out.println("while terminated"); //Compiler-error - unreachable statement.
while(true) {
if(true) {
System.out.println("inside if");
return;
}
System.out.println("inside while"); //No error here.
}
System.out.println("while terminated"); //Compiler-error - unreachable statement.
**编辑:**同名的内容:if和while。
if(false) {
System.out.println("inside if"); //No error here.
}
while(false) {
System.out.println("inside while");
// Compiler's complain - unreachable statement.
}
while(true) {
if(true) {
System.out.println("inside if");
break;
}
System.out.println("inside while"); //No error here.
}
以下版本的while也会陷入无限循环。
while(true) {
try {
System.out.println("inside while");
return; //Replacing return with break makes no difference here.
} finally {
continue;
}
}
这是因为finally24块总是被执行,即使return语句在try块本身之前遇到它。
#1 热门回答(105 赞)
编译器可以轻松而明确地证明第一个表达式路径会产生无限循环,但对于第二个而言并不容易。在你的玩具示例中它很简单,但如果:
从文件中读取变量的内容?
变量不是本地的,可以被另一个线程修改?
变量依赖于一些用户输入?
编译器显然没有检查你的简单案例,因为它完全放弃了这条道路。为什么?因为这个规格很难被禁止。 Seesection 14.21:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.21-300-M
(顺便说一下,我的编译器会在变量声明为final时进行压缩。)
#2 热门回答(55 赞)
根据specifications,以下是关于while语句的说法。
如果至少满足下列条件之一,则while语句可以正常完成:while语句可以访问,条件表达式不是值为true的常量表达式。有一个可到达的break语句退出while语句。
因此,编译器只会说如果while条件是具有true值的常量,或者while内有break语句,则while语句后面的代码是不可达的。在第二种情况下,由于b的值不是常数,因此不认为其后面的代码是不可达的。该链接背后有更多信息,可以为你提供有关什么是不可达的内容和更多内容的更多详细信息。
#3 热门回答(14 赞)
因为true是常数,b可以在循环中改变。