给出以下示例:
class A {
public static void main(String[] args) {
int n=5;
int k;
while(n<6) {
k=5;
break;
}
System.out.println(k);
}
}
和:
class B {
public static void main(String[] args) {
int k;
while(true) {
k=5;
break;
}
System.out.println(k);
}
}
我知道第一个示例将无法正常运行,因为 k 尚未被明确分配;而第二个例子可以运行。
然而,当我尝试使用形式化的定赋值规则来判断这两个例子时,却无法对它们做出准确的判断。我使用的规则来自
JLS:
16.2.10 while 语句比如我在判断第二个例子的时候,如果•
V
在while (e) S
(第 14.12) 后被[取消]分配,当且仅当V
被[取消]分配 当 false 时在e
之后并且V
在每个break语句之前被[un]分配 其中 while 语句是中断目标。•
V
肯定先于e
赋值,当且仅当V
肯定已赋值 在 while 语句之前。•
V
在e
之前肯定未分配,前提是以下所有内容均已满足 true: –V
在 while 语句之前肯定是未赋值的。 – 假设V
在e
之前肯定未分配,则V
肯定是S
后未分配。 – 假设V
在e
之前肯定未分配,V
在每个 continue 语句之前绝对未分配 while 语句是 continue 目标。•
V
在S
之前[取消]分配,当且仅当为 true 时,V
在e
之后[取消]分配。
e
为true,那么似乎只能应用最后一条规则,但是这个规则似乎并不能确定
k
已经肯定被应用了已分配。那么,如何判断上面的例子是否已经按照规范
明确分配了?感谢您的阅读和回答。
e
的计算结果为
false
,那么在计算
V
后,必须明确地对
e
进行赋值。此外,必须在每个打破循环的
V
之前明确分配
break
。如果这些条件成立,那么
V
肯定会在循环之后被赋值。在第二个例子中,
true
不可能计算为
false
,所以第一个条件成立。
k=5;
之前的
break;
意味着
k
肯定在
break
之前被赋值,所以第二个条件也成立。因此,
k
在循环之后肯定被赋值。