2

假设我有下面一段代码为什么java编译器不能识别字段已被初始化?

int myVar; 
final boolean condition = <someCondition>; 
if (condition) { 
    myVar = 1; 
} 
if (condition) { 
    System.out.println("myVar = " + myVar); 
} 

当我编译此,我得到了预期myVar might not have been initialized错误。 这是编译器中的错误吗?当condition为真时很容易看到“myVar”被设置,并且仅在condition为真时才被引用。 (condition也永远不会重置)

P.S:对于那些对我的评论需要初始化为0,是的,我意识到这一点。但问题是,我想“myVar的”要最终

+1

@imk这是相当明显的OP已经知道,因为这个问题的整点是关于*为什么*编译器需要初始化。 – azurefrog

+4

Java编译器根本没有做足够深入的分析,得出结论:在使用变量'myVar'之前,一个值总是被分配给变量'myVar'。一般来说,它不会尝试关联不同条件语句中的条件。 –

+0

我不认为编译器意识到这种情况不会改变。举例来说,这是在一个中断的CPU上运行。条件可能会改变,当它回到执行此。 没关系,我没有看条件的声明。 @JohnBollinger看起来足够了。 – bhow

回答

4

初始化要求是Java的正式组成部分,如JLS描述(即值设置最多一次。):

对于局部变量或空白最终字段x的每次访问,x必须在访问之前明确分配,或发生编译时错误。

JLS 8, chapter 16;重视在原)

的JLS接着说

分析考虑到了报表和 表达的结构;它还提供了对表达式 运算符!,&&,||? :以及布尔值常数 表达式的特殊处理。

除条件布尔运算符 &&||,和? :和布尔值常量表达式,值 表达式中的特殊处理是没有考虑到在流分析

(强调)

注意清楚conditionfinal不使其成为“常量表达式”作为规范定义了术语。本说明书中的推移,得到the specific rule for if statements

V是[未] if (e) S之后分配IFF V是[未]分配后SV是[未] e后分配时[e计算结果为[false

在您的特定代码,然后:

int myVar; 

myVar绝对是这里分配。

final boolean condition = <someCondition>; 
if (condition) { 
    myVar = 1; 
} 

myVar是 “S后分配”,因为S,该if语句体,进行无条件转让。 myVar而不是在评估条件后指定,但是,条件是否评估为truefalse。因此,myVar在这个方法中没有明确指定。

if (condition) { 

并没有发生什么变化,在这一点上:myVar仍然没有明确至于JLS规则而言分配,因此它的价值不能被读取。因此,编译器有义务在未来的声明报告错误:

System.out.println("myVar = " + myVar); 
} 
相关问题