如何判断下面的例子是否确定赋值?

问题描述 投票:0回答:1

给出以下示例:

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章前面部分对大量示例的粗略解释。

然而,当我尝试使用形式化的定赋值规则来判断这两个例子时,却无法对它们做出准确的判断。

我使用的规则来自

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
已经肯定被应用了已分配。

那么,如何判断上面的例子是否已经按照规范

明确分配了?感谢您的阅读和回答。

java language-lawyer
1个回答
0
投票
你已经被令人困惑的句子结构搞混了。这里的相关规则在第一个要点中。让我们来分解一下:

    V 在 while (e) S (§14.12) iff 之后被[un]赋值
    • 当为 false 且
    • 时,V 在 e 之后被[un]赋值
    • V 在每个以 while 语句为中断目标的中断语句之前被分配。
这意味着需要满足两个条件:如果

e

 的计算结果为 
false
,那么在计算 
V
 后,必须明确地对 
e
 进行赋值。此外,必须在每个打破循环的 
V
 之前明确分配 
break
。如果这些条件成立,那么 
V
 肯定会在循环之后被赋值。

在第二个例子中,

true

不可能计算为
false
,所以第一个条件成立。 
k=5;
之前的
break;
意味着
k
肯定在
break
之前被赋值,所以第二个条件也成立。因此,
k
在循环之后肯定被赋值。

© www.soinside.com 2019 - 2024. All rights reserved.