阻止范围变量

这将编译

class X { public static void main(String args[]) { { int a = 2; } { int a = 3; } } } 

这不会

 class X { public static void main(String args[]) { int a = 2; { int a = 3; } } } 

我期望两者都编译(也许这是C的工作方式?)。 是什么原因是因为无法在外部块中使用相同名称的块声明变量?

简短的回答是:因为这是JLS§6.4中定义Java语言的方式。

您可能会在其他语言中使用这种所谓的变量阴影 。 然而,Java语言的发明者认为这是一个他们不想用他们的语言的尴尬function:

此限制有助于检测一些非常模糊的错误。

但是,您可以在Java的其他位置找到阴影,因为作者在JLS的相同部分中声明:

对局部变量对成员进行阴影的类似限制被认为是不切实际的,因为在超类中添加成员可能导致子类必须重命名局部变量。 相关的考虑因素限制了嵌套类成员对局部变量的阴影,或者对嵌套类中声明的局部变量的局部变量的阴影也没有吸引力。

这实际上意味着以下代码是合法的:

 class A { int x = 0; void m() { int x = 10; // Shadows this.x } } 

正如作者所描述的那样,允许通过声明一个具有相同名称的方法局部变量来影响实例变量,因为有人可能会在某一天扩展A的function,如果阴影是非法的,则无法再编译B类:

 class B extends A { void m() { int x = 10; // Shadows A.this.x if A declares x } } 

如果你考虑像C这样的语言,允许使用阴影,你可以找到这样的尴尬代码:

 int x; int main() { { int x = 0; { extern int x; x = 1; } printf("%d\n", x); // prints 0 } printf("%d\n", x); // prints 1 return 0; } 

由于可变阴影,该程序不易遵循,因此可能无法产生您期望的结果。

Java不允许您在两个范围内具有相同名称的两个变量。

在你的第二种情况:

 int a = 2; { // the outer 'a' is still in scope int a = 3; // so this is a redeclare <-- nooo! } 

但是,在你的第一种情况下,每个a都包含在自己的范围内,所以一切都很好。

因为在第二种情况下,静态块内部已知a ,因此您尝试重新声明它。 编译器不允许您这样做:

 public static void main(String args[]) { { int a = 2; //a is known only here } //a will be freed { int a = 3; //you can declare it again here } } 
 public static void main(String args[]) { int a = 2; // I know a // I know a { // I know a int a = 3; // There can be only one a! } } 

在上面的示例中,您在方法main()声明a 。 从声明到方法结束,声明了a 。 在这种情况下,你需要在你的代码块中重新安装一个。

下面,您在块中声明a 。 它只在内部被人知道。

 public static void main(String args[]) { { int a = 2; // I know a // I know a } // Who is a? { int a = 3; // I know a! } } 

在Java中,所有局部变量都将存储在Stack上。 所以,如果你写

 class X { public static void main(String args[]) { int a = 2; // At this point var 'a' is stored on Stack { /* Now as the prev. 'main method is not yet complete so var 'a' is still present on the Stack. So at this point compiler will give error "a is already defined in main(java.lang.String[])" */ int a = 3; } } } 

希望这可以帮到你

谢谢