说我在本地方法中有一段代码
int a = 5, b;
然后使用一些代码间接初始化B,例如
if (true) b = 5; // legal
if (someBool) b = 10; else b = 7; // legal
if (false) b = 5; // illegal
即使B总是被初始化也是非法的
if (a > 10)
b = 4;
if (a <= 10)
b = 4;
我的问题是,在什么情况下可以合法地将局部变量合法地“初始化”?
如果编译器可以轻松推断出每个可能的代码路径将通过设置了该值的路径,则可以认为局部变量是“初始化的”。
if(true)
可以确定始终运行。if(false)
可以确定永远不会运行。if/else
可以确定运行至少一个分支,因此如果要确保已初始化变量,则必须在每个分支中分配变量。同样的原则适用于if/else if/.../else
switch
语句将运行可能的case
s之一,或者会遇到这种default
情况,因此,如果在所有这些位置分配变量,则可以保证将其初始化。确定时,Java编译器不会费心地检查方法中各个点上每个变量的所有可能值,因为变量是可变的-它们可以更改。但是,如果可以将值视为常量,则可以放心地假设它们不会改变。
例如,编译器不在乎是否分配变量,并且永远不要在代码中更改它:
boolean val = true;
if(val) {
b = 5;
}
调试器和其他工具使您可以val
即时更改值,因此编译器在此不做任何假设。但是,如果您通过声明val
常量final
并使用常量或文字值对其进行初始化来使它成为常量,则编译器将对它的处理方式与在代码中使用常量值的方式完全相同。
final boolean val = true;
if(val) { // Same as if you'd said `if(true)`
b = 5;
}
这样的常量也可以被链接,并且编译器会将它们简化为它们的常量值,而不是维护更长的表达式和运算符:
final int five = 5;
final int four = five - 1; // Same as `four = 5 - 1`, or `four = 4`
final boolean val = five > four;
if(val) { // Same as `if(5 > 4)`, or `if(true)`
b = 5;
}
要进一步阅读,请查看Java Specs。(向Radiodef提示有关正确部分的技巧。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句