为什么java编译器不识别字段已初始化?

时间:2017-10-12 17:16:58

标签: java variables compiler-errors variable-initialization javacompiler

假设我有以下代码

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

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

P.S:对于那些需要将其初始化为0的评论,是的,我知道这一点。但问题是,我想要&#34; myVar&#34;是最终的(即,最多设定一次的值)

1 个答案:

答案 0 :(得分:4)

初始化要求是Java的正式部分,如JLS中所述:

  

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

JLS 8, chapter 16;强调原文)

JLS继续说

  

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

     

除了条件布尔运算符的特殊处理   &&||? :以及布尔值常量表达式 值   在流程分析中不考虑表达式

(强调补充)

请注意condition final不会使其成为“常量表达式”,因为规范定义了该术语。规范继续给出the specific rule for if statements

  V if (e) S之后VS分配Vee分配falseint myVar; myVar分配后被取消final boolean condition = <someCondition>; if (condition) { myVar = 1; } 1}}当[myVar评估为if时。

在您的特定代码中,然后:

myVar

true肯定是 un 在这里分配的。

false

myVar是“在S之后分配”,因为S是if (condition) { 语句的主体,执行无条件赋值。在评估条件后,myVar 分配,但条件是评估为 System.out.println("myVar = " + myVar); } 还是# go-carbon.aggregation [sum_counts] pattern = ^stats_counts.* xFilesFactor = 0 aggregationMethod = sum # /go-carbon.schemas [default_1min_for_7days_and_1hour_for_5years] pattern = .* retentions = 1m:30d,1h:5y 。因此,此方法中此时未明确指定sum

aggregationMethod

此时没有任何变化:就{JLS规则而言 - stats_counts.test.monitor.remote.datapoint 仍未明确分配,因此不得读取其值。因此,编译器有义务在下一个语句中报告错误:

{{1}}