我有个准则
final int a, b;
a = b = 10;
while (a <= b) {
System.out.println("this is in while loop");
}
System.out.println("this is out of while loop");
在本例中,我的while块执行了无限次。
在有另一个代码
final int a=10;
final int b = 10;
while (a <= b) {
System.out.println("this is in while loop");
}
System.out.println("this is out of while loop");
在这种情况下,我得到编译错误,提到while循环外的语句代码不可达
即使它们是最终变量。我试图在这两种情况下分别重新分配变量a和b的值,但我不能在这两种情况下重新分配值,因为它是最终变量。但是在我提到的第一种情况下,它们不被认为是常数,这是循环重复的原因。
2条答案
按热度按时间xqk2d5yq1#
虽然在两种情况下变量都是
final
,但第二种情况下的变量也是 * 常量变量 *:常量变量是原始类型或String类型的最终变量,它用常量表达式初始化(§15.29)。一个变量是否是常量变量可能会影响[...]可达性(§14.22)[...]。
第一种情况下的变量不是常量变量,因为它们没有初始化。它们在下一个语句中赋值。注意final变量不需要初始化=它们只需要是definitely assigned。
这使得第二个代码中的
a <= b
成为一个 * 常量表达式 *,其常量值为true
。这会影响一个语句是否 * 可达 *。请参阅本节中的相关引文。如果某个语句由于不可访问而无法执行,则这是一个编译时错误。
非空块中的第一个语句是可达的,当且仅当该块是可达的。
非空块中的每一个语句S都是可达的,当且仅当S前面的语句可以正常完成。
break
语句。在这种情况下,由于
while
语句确实有一个常量true
条件,并且没有break
s,因此while
语句无法正常完成。这会导致while循环后的语句不可访问。agyaoht72#
我用一种不专业的方式来解释这个现象,测试类如下:
用javac编译后,用javap反编译的结果如下:
注意m3,return的值直接换成20!
计算m1和m2两者,即特定值 直到运行阶段才知道。
因此,可以得出下一个结论,m3中的值实际上可以在编译阶段确定。如果将它作为条件放入while中,则可以在编译阶段知道结果。