为什么';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
iff
V
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);
}