2017-11-10 151 views
1

这是参照在编译器检查本地变量k的初始化程序错误时确定分配的变量。变量的明确赋值

void flow(boolean flag) { 
    int k; 
    if (flag) 
     k = 3; 
    if (!flag) 
     k = 4; 
    System.out.println(k); 
} 

这段代码抛出一个编译错误:

k needs to be initialized.

在下面的情况下,无论什么flag变量的值时,k变量的值将被分配。这个编译错误是否合理?

+3

编译器不够聪明,如果你不使用'else',就知道你已经检查了两个标志条件。使用'else'。 –

+3

更好的问题是,这段代码是否合理?你为什么要明确检查一个布尔值的两边? – shmosel

+2

更好的版本是:'final int k = flag? 3:4;'一行而不是五,更好理解,作为一个加号,变量'k'是不可变的。 – vanje

回答

2

这是因为编译器不检查所有可能的不是最终的字段值(这里是flag)。

编译器只能分析编译时常量并确认局部变量是否会被初始化。

更多关于这在Java语言规范:https://docs.oracle.com/javase/specs/jls/se7/html/jls-16.html

考虑两个以上相同方法的变化...

在这里,即使编译器知道标志的值,它会抛出编译器错误变量k。

void flow() { 
    boolean flag = false; 
    int k; 
    if (flag) 
     k = 3; 
    if (!flag) 
     k = 4; 
    System.out.println(k); 
} 

这里作为标志为一个编译时间常数,编译器可以计算出变量k和的值,因此没有编译错误

void flow() { 
    final boolean flag = false; 
    int k; 
    if (flag) 
     k = 3; 
    if (!flag) 
     k = 4; 
    System.out.println(k); 
} 
+0

这确实清除了我的疑问。编译时常量是我主要寻找的东西。 – Ronald

2

是的,的确,变量k将被初始化,而不管它的状态如何。但是,因为两个if条件彼此不相关,所以编译器无法保证变量k将在控制进入println方法调用时被初始化。

我假设你知道修复手头上的问题,但如果不是这样,你只需要删除第二if语句,然后链中else块到第一if声明。

+0

这是我在阅读教程时遇到的代码,我相信解决方案是编译时常量,是的,我知道代码修复此:)谢谢 – Ronald