为什么不能在if语句中声明变量?

以下Java代码无法编译。

int a = 0; if(a == 1) { int b = 0; } if(a == 1) { b = 1; } 

为什么? 没有代码路径可以导致程序在不先声明的情况下分配1到b

在我看来, b的变量范围可能仅限于第一个if语句,但后来我不明白为什么。 如果我真的不想不必要地声明b ,以提高性能怎么办? 声明后,我不喜欢让变量闲置。

(你可能想争辩,但我可以简单地在第二个if语句中声明b,在这种情况下,想象一下它可能在其他地方的循环中。)

为什么? 没有代码路径可以导致程序在不先声明的情况下分配1到b。

你是对的,但编译器不知道。 编译器不执行代码。 编译器仅转换为字节码而不评估表达式。

变量可以在条件语句中声明。 但是,您尝试在不同的范围内访问b

当你在这里声明b时:

 if(a == 1) { int b = 0; } 

它只在范围内直到结束}

因此,当你来到这一行:

 b = 1; 

b不存在。

这个{ }定义了一个块范围。 在{}之间声明的任何内容都是该块的本地内容。 这意味着您不能在块之外使用它们。 但是,Java不允许在内部块中使用内部名称隐藏名称。 这就是JLS所说的:

块(第14.2节)中局部变量声明的范围是声明出现的块的其余部分,从其自己的初始化器(第14.4节)开始,并包括局部变量声明语句中右侧的任何其他声明器。

局部变量v的名称可能不会被重新声明为v范围内的直接封闭方法,构造函数或初始化程序块的局部变量,或者发生编译时错误。

它是关于java变量范围的。

您需要在if statement之外定义variable才能在外部使用它。

 int a = 0; int b = 0; if(a == 1) { b = 1; } if(a == 1) { b = 2; } 

请参阅块和语句

它是一个局部变量,仅限于{}范围。

试试这里 。

如果在if块旁边无法访问的块,你已经在内部声明了b变量,如果你想访问那么就把它放在if块之外

b的范围是它声明的块,即第一个if。 为什么? 因为这个范围规则(词法范围)易于理解,易于实现,并遵循最少惊喜的原则。

如果b在第二个中可见:

  • 编译器必须推断等价的if分支并将它们合并到一个范围(难以实现);
  • 在随机if语句中更改条件可能会使某些变量可见,而其他变量则隐藏(难以理解并出现令人惊讶的错误)。

没有理智的语言有这么复杂的范围规则。

wrt性能 – 声明一个额外的变量对性能的影响可以忽略不计。 相信编译器! 它将有效地分配寄存器。

因为当b超出第一个if(a == 1)中的范围时,它将被删除并且不再存在于堆栈中,因此不能在下一个if语句中使用。

{ }用于定义变量的范围。在这里你声明:

 if(a == 1) { int b = 0; } 

所以这里b的范围只在{ } 。所以你在{ }之外使用变量b,它给出了编译错误。

你也可以参考:

http://docs.oracle.com/javase/tutorial/java/javaOO/variables.html

如果在块中声明变量,则变量的限制将限制为声明它的特定块。

注意:只有静态变量可以从程序中的任何位置访问。

在你的代码中:

 int a = 0; if(a == 1) { int b = 0; } if(a == 1) { b = 1; } 

变量’a’可以在任何if语句中访问,因为它在块外声明,但变量’b’在内部声明,因此限制了它在块外的使用。

如果你想在if语句之外使用’b’,你必须在声明变量’a’的地方声明它。

 int a = 0; if(a == 1) { int b = 0; // this int b is only visible within this if statement only(Scope) } if(a == 1) { b = 1; // here b can't be identify } 

你必须按照以下方式纠正错误

  int a = 0; int b = 0; if(a == 1) { b=0; } if(a == 1) { b = 1; } 

只是为了完整起见:这个也适用(解释是范围界定,请参阅其他答案)

 int a = 0; if(a == 1) { int b = 0; } if(a == 1) { int b = 1; } 

由于范围界定,b只能在if语句中访问。 我们这里有两个变量,每个变量都可以在它们的范围内访问。

变量b的范围仅在if块完成之前,因为这是您声明变量的地方。 这就是为什么无法在以下块中访问它。 这是用于内存分配,否则它们将在内存中浮动很多变量。

 int a = 0; if(a == 1) { int b = 0; } //b scope ends here if(a == 1) { b = 1; //compiler error }