2

假设我有以下代码

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

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

PS:对于那些关于我需要将其初始化为 0 的评论,是的,我知道这一点。但关键是,我希望“myVar”是最终的(即,最多设置一次值)

4

1 回答 1

4

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

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

JLS 8,第 16 章;原文强调)

JLS 继续说

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

除了条件布尔运算符 &&||、 和的特殊处理之外,在流分析中不考虑? :表达式的值。

(重点补充)

请注意,正如规范定义的那样,condition存在final并不使其成为“常量表达式”。规范继续给出语句的具体规则if

Vis [un]assigned after if (e) Sif Vis [un]assigned after Sand Vis [un]assigned after ewhen [e评估为] false

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

int myVar;

myVar绝对是分配的。

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

myVar是“在 S 之后赋值”,因为if语句体 S 执行无条件赋值。 在评估条件后不myVar赋值,但是,无论条件评估为还是. 因此,在方法中的这一点上并不一定是指定的。truefalsemyVar

if (condition) {

在这一点上没有任何改变:myVar就 JLS 规则而言,仍然没有明确分配,所以它的值不能被读取。因此,编译器有义务在下一条语句中报告错误:

   System.out.println("myVar = " + myVar);
}
于 2017-10-12T17:43:25.460 回答