为什么';java编译器识别字段是否已初始化?
假设我有下面的代码为什么';java编译器识别字段是否已初始化?,java,variables,compiler-errors,variable-initialization,javacompiler,Java,Variables,Compiler Errors,Variable Initialization,Javacompiler,假设我有下面的代码 int myVar; final boolean condition = <someCondition>; if (condition) { myVar = 1; } if (condition) { System.out.println("myVar = " + myVar); } int-myVar; 最终布尔条件=; 如果(条件){ myVar=1; } 如果(条件){ System.out.println(“myVar=“+myVar”);
int myVar;
final boolean condition = <someCondition>;
if (condition) {
myVar = 1;
}
if (condition) {
System.out.println("myVar = " + myVar);
}
int-myVar;
最终布尔条件=;
如果(条件){
myVar=1;
}
如果(条件){
System.out.println(“myVar=“+myVar”);
}
当我编译这个时,我得到了预期的myVar可能没有初始化的错误。
这是编译器中的错误吗?很容易看出,“myVar”是在条件
为真时设置的,并且仅在条件
为真时才被引用。(条件
也从不重置)
注:对于那些我需要将其初始化为0的评论,是的,我知道这一点。但关键是,我希望“myVar”是最终的(即,最多设置一次值)初始化要求是Java的一个正式部分,如JLS中所述:
对于局部变量或空白最终字段x的每次访问,必须在访问之前明确指定x,否则会发生编译时错误。
(;原文强调)
JLS接着说
该分析考虑了报表和报表的结构
表达;它还提供了对表达式的特殊处理
操作员代码>、和&
、和:代码>,且为布尔值常量
表情
除了对条件布尔运算符的特殊处理
&&
,|
和?:代码>和布尔值常量表达式,值
流量分析中不考虑表达式的数量
(增加重点)
请注意,condition
作为final
并没有使其成为“常量表达式”,因为规范定义了该术语。规范接着给出了:
V
在之后被[取消]分配,如果(e)S
iffV
在S
之后被[取消]分配,并且当[e
计算结果为]false
时,V
在e
之后被[取消]分配
在您的特定代码中,然后:
myVar
在这里肯定是未分配的
在这一点上没有任何变化:myVar
就JLS规则而言,仍然没有明确分配,因此不能读取其值。因此,编译器有义务在下一条语句中报告错误:
@imk OP显然已经知道了这一点,因为问题的关键是编译器为什么需要初始化。Java编译器只是没有进行足够深入的分析,得出结论,变量myVar
在使用之前总是被赋值。一般来说,它不会尝试将不同条件语句中的条件关联起来。我不认为编译器知道条件不会改变。例如,它在中断的CPU上运行。当返回执行此操作时,条件可能会更改。没关系,我没有看状态声明。@JohnBollinger的内容似乎足够了。我很感兴趣地尝试了这个特定场景,它在jdk1.8.0_141.@d.j.brown中使用javac编译和运行时没有问题,这是因为您将编译时常量true
指定给了条件。如果使用运行时值初始化它,它将失败。
int myVar;
final boolean condition = <someCondition>;
if (condition) {
myVar = 1;
}
if (condition) {
System.out.println("myVar = " + myVar);
}