在Java中,什么确切地构成了;初始化局部变量“?”;?

在Java中,什么确切地构成了;初始化局部变量“?”;?,java,Java,假设我在本地方法中有一段代码 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(a>10) b=4; 如果(a局部变量可以被认为是“初始化的”,如果编译器

假设我在本地方法中有一段代码

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(a>10)
b=4;

如果(a局部变量可以被认为是“初始化的”,如果编译器可以很容易地推断出每个可能的代码路径都将通过一个设置了值的路径

  • if(true)
    可确定始终运行
  • if(false)
    可确定为从不运行
  • if/else
    可以被确定为运行至少一个分支,因此如果希望保证初始化,则必须在每个分支中分配变量。相同的原则适用于
    if/else if/../else
  • switch
    语句将运行一个可能的
    case
    s,或者将命中
    default
    case,因此如果您在所有这些位置分配变量,则可以保证将其初始化
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;
}
如需进一步阅读,请查看。(Radiodef的帽子提示以查找右侧部分。)

在这种情况下:

if (false) b = 5;  // illegal
int a = 5, b;
if (a > 10)
b = 4;
if (a <= 10)
b = 4;
编译器抛出一个异常,因为
if(false)
可以在编译时被擦除。即使分析一个无法执行的代码块也是徒劳的

在这种情况下:

if (false) b = 5;  // illegal
int a = 5, b;
if (a > 10)
b = 4;
if (a <= 10)
b = 4;
但请注意,您仍然可以通过给
final int a
一个编译器无法确定的值来中断此代码:

final int a = foo();
int b;
if (a > 10)
    b = 4;
if (a <= 10)
    b = 4;

//...

int foo() {
    return 5;
}
final int a=foo();
int b;
如果(a>10)
b=4;

如果(a)问题目前过于宽泛(“具体情况如何”)。JLS用了整整一章来讨论这个问题,叫做。答案是编译器只能做这么多。所以,要么总是显式初始化局部变量,要么期望编译器偶尔不能做出决定。IDE通常会指出什么可以决定,什么不能决定。我不明白你说的“ille”是什么意思gal'和'legal'。
如果(false)b=5;
没有意义。
b=5;
在那种情况下是死代码。我把这个吸盘放进我的IDE,它按它应该的方式打印。我把
someBool
设置为
false
,打印出b,得到7。我把
someBool
设置为
true
,打印出b,得到10。@VinceEmigh的意思是“合法使用”(也就是说,保证初始化)vs not。@Radiodef整个章节(可能减去一些示例)这个问题的答案是正确的。事实上,我认为这是唯一正确的答案。你能在JLS找到一个参考吗?我搜索过但是我找不到它。@ MelLinux 2011年阅读了下面的第一个评论。@ DavidWallace,谢谢。我刚刚看到了。谢谢你的评论。我包括了完整的链接。nal布尔值5=5;不知道这在Java中是合法的;)