为什么java编译器不能识别字段已被初始化?
假设我有下面一段代码为什么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的”要最终
初始化要求是Java的正式组成部分,如JLS描述(即值设置最多一次。):
对于局部变量或空白最终字段x的每次访问,x必须在访问之前明确分配,或发生编译时错误。
(JLS 8, chapter 16;重视在原)
的JLS接着说
分析考虑到了报表和 表达的结构;它还提供了对表达式 运算符
!
,&&
,||
和? :
以及布尔值常数 表达式的特殊处理。除条件布尔运算符
&&
,||
,和? :
和布尔值常量表达式,值 表达式中的特殊处理是没有考虑到在流分析。
(强调)
注意清楚condition
是final
不使其成为“常量表达式”作为规范定义了术语。本说明书中的推移,得到the specific rule for if
statements:
V
是[未]if (e) S
之后分配IFFV
是[未]分配后S
和V
是[未]e
后分配时[e
计算结果为[false
。
在您的特定代码,然后:
int myVar;
myVar
绝对是未这里分配。
final boolean condition = <someCondition>; if (condition) { myVar = 1; }
myVar
是 “S后分配”,因为S,该if
语句体,进行无条件转让。 myVar
是而不是在评估条件后指定,但是,条件是否评估为true
或false
。因此,myVar
在这个方法中没有明确指定。
if (condition) {
并没有发生什么变化,在这一点上:myVar
仍然没有明确至于JLS规则而言分配,因此它的价值不能被读取。因此,编译器有义务在未来的声明报告错误:
System.out.println("myVar = " + myVar); }
@imk这是相当明显的OP已经知道,因为这个问题的整点是关于*为什么*编译器需要初始化。 – azurefrog
Java编译器根本没有做足够深入的分析,得出结论:在使用变量'myVar'之前,一个值总是被分配给变量'myVar'。一般来说,它不会尝试关联不同条件语句中的条件。 –
我不认为编译器意识到这种情况不会改变。举例来说,这是在一个中断的CPU上运行。条件可能会改变,当它回到执行此。 没关系,我没有看条件的声明。 @JohnBollinger看起来足够了。 – bhow