5

这是Java语言的代码片段:

 public void name(){
int value = 9;
 int o;
if(value > 9)
 o = 5;

if(value <= 9)
o = 8;

System.out.println(o);
}

考虑到值的最后一个选项,为什么编译器看不到第二个 if 语句?它不会编译。最好的祝福

4

5 回答 5

5

value除非您另有说明,否则编译器必须将其视为可变的。声明它可以final 解决问题

public void name(){
    final int value = 9;
    int o;
    if(value > 9) o = 5;
    if(value <= 9) o = 8;
    System.out.println(o);
}
于 2012-10-17T14:29:36.633 回答
1

原始版本无法编译的原因是JLS 第 16 节中的 JLS 的“确定分配”规则说o尚未确定分配。编译器会用一条神秘的消息报告这一点,上面写着“o可能尚未初始化”。

现在,任何具有简单演绎技巧的人都可以看出,第二个if条件是第一个if条件的否定,因此变量实际上总是会被初始化。但是,JLS 不允许编译器进行该推论。JLS 说这是一个错误...

有很多方法可以解决这个问题。例如

  • o在声明中分配一些东西。
  • if用单个if/语句替换这两个else语句。
  • 声明valuefinal

最后一个修复很有趣。它起作用的原因是 JLS 明确分配规则要求编译器将编译时常量布尔值表达式的值考虑在内。

本声明(附final

    final int value = 9;

意味着这value是一个编译时常量。这意味着value <= 9并且value > 9也是编译时常量。因此,JLS 明确分配规则指出,o在之后明确分配

    if(value <= 9) o = 8;

并且可以在以后使用而不会出现编译错误。


明确的赋值规则旨在防止使用未初始化的变量,并防止空白final变量被多次初始化。

JLS 在明确分配规则中对表达式值的保守处理旨在避免出现以下问题:一个 Java 编译器推断出某些东西是明确分配的,而另一个则不能。编译时常量表达式的子情况可以通过简单地计算表达式来处理,JLS 规则隐含地认识到这一点。

于 2012-10-17T15:22:17.870 回答
0

编译期间:

编译器发现您尚未初始化变量 'o' 并且您正在 sysout 中打印。

你可以做到这一点:

public void name(){
int value = 9;
 int o;
if(value > 9)
 o = 5;

else
o = 8;

System.out.println(o);
}
于 2012-10-17T14:29:09.690 回答
0

在声明它之后在 if 语句之前初始化 o

o=0;
于 2012-10-17T14:30:48.780 回答
0

根据 JLS (第 16 节),每个局部变量和非空白字段必须在使用之前明确分配。编译器会做一些基本的静态分析来确保它。

明确赋值背后的想法是,对局部变量或空白最终字段的赋值必须发生在访问的每个可能的执行路径上。类似地,明确取消赋值背后的想法是不允许在任何可能的赋值执行路径上发生对空白最终变量的其他赋值。

静态分析器只能推断出常量表达式的值(15.28 美元),而在您的示例中并非如此。

于 2012-10-17T14:52:34.420 回答