这被看作是代码的Java语言中的片段:分支无法通过编译器
public void name(){
int value = 9;
int o;
if(value > 9)
o = 5;
if(value <= 9)
o = 8;
System.out.println(o);
}
为什么编译器看不到第二个if语句考虑价值的最后一个选项? 它不会编译。 最好的问候
这被看作是代码的Java语言中的片段:分支无法通过编译器
public void name(){
int value = 9;
int o;
if(value > 9)
o = 5;
if(value <= 9)
o = 8;
System.out.println(o);
}
为什么编译器看不到第二个if语句考虑价值的最后一个选项? 它不会编译。 最好的问候
编译器必须把value
为可更改。声明它final
fixes the problem:
public void name(){
final int value = 9;
int o;
if(value > 9) o = 5;
if(value <= 9) o = 8;
System.out.println(o);
}
我很惊讶它不能轻易推测它在这种情况下是不可变的 –
@BrianAgnew我只能猜测编译器不允许将两个'if'中的两个读取值视为访问相同的价值(并因此使两个条件互补)。 – dasblinkenlight
编译器只能在检查明确赋值时对常量表达式进行操作。 'value> 9'和'value <= 9'都不是常量表达式,除非'value'是常量变量,它本质上是一个'final'变量。 – pingw33n
在编译:
编译器看到的,你没有初始化的变量的“o”,你是在系统输出打印。
你可以做到这一点:除非你说,否则
public void name(){
int value = 9;
int o;
if(value > 9)
o = 5;
else
o = 8;
System.out.println(o);
}
初始化Ø前if语句声明后
o=0;
原始版本无法编译的原因是JLS section 16中的JLS'“明确分配”规则说o
尚未明确分配。编译器用一个神秘的消息报告这个消息,说“o
可能没有被初始化”。
现在,任何具有简单演绎技巧的人都会看到第2个if
条件是否定第1个条件,因此该变量实际上总是会被初始化。但是,JLS不允许编译器进行扣除。 JLS说这是一个错误...
有很多方法可以解决这个问题。例如
o
。if
语句替换为单个if
/else
语句。value
为final
。上次修复很有趣。它的工作原理是JLS明确的分配规则需要编译器将编译时常量布尔值表达式的值考虑在内。
本声明(与final
加)
final int value = 9;
意味着value
是一个编译时间常数。这意味着value <= 9
和value > 9
也是编译时常量。因此,JLS明确分配规则指出o
之后
if(value <= 9) o = 8;
明确指定的,可没有一个编译错误以后使用。
明确赋值规则旨在防止使用未初始化的变量,并防止空白final
变量初始化一次以上。
JLS在明确赋值规则中对表达式值的保守处理旨在避免一个Java编译器推断出明确赋值,但另一个不能赋值的问题。编译时常量表达式的子表达式可以通过简单地评估表达式来处理,并且JLS规则隐式识别这个表达式。
错误是:变量o可能没有被初始化(System.out.println(o)) –
为什么两个if语句而不是if..else? – CBredlow
我只是在探索语言。这两个陈述没有特别的理由。 – uml