假设我在本地方法中有一段代码
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
之一,或者将命中default
case,因此如果您在所有这些地方都可以保证初始化。
Java 编译器在做出此决定时不会在方法的不同点检查每个变量的所有可能值,因为变量是可变的——它们可以改变。但是,如果可以将值视为常量,那么它可以安全地假设它们不会改变。
例如,编译器不关心您是否分配了一个变量并且从不在您的代码中更改它:
boolean val = true;
if(val) {
b = 5;
}
调试器和其他东西使您可以即时更改 val
的值,因此编译器不会在这里做任何假设。但是,如果您将 val
constant 声明为 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 - 在 Java 中,什么是 "initializing a local variable"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23207471/