说我在本地方法中有一段代码
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如果/…/else同样的原则
> switch语句将运行一种可能的情况,或者将达到默认情况,因此,如果在所有这些位置分配变量,则可以保证将其初始化.
进行此确定时,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的帽子提示,以找到正确的部分.)
标签:java
来源: https://codeday.me/bug/20191029/1961471.html