这将编译
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的工作方式?)。是什么原因是因为无法在外部块中使用相同名称的块声明变量?
答案 0 :(得分:15)
简短的回答是:因为这是在JLS §6.4中定义Java语言的方式。
您可能会在其他语言中使用这种所谓的variable shadowing。然而,Java语言的发明者认为这是一个他们不想用他们的语言的尴尬功能:
此限制有助于检测一些非常模糊的错误。
但是,您可以在Java的其他地方找到阴影,因为作者在JLS的同一部分中说明了这一点:
对局部变量对成员进行阴影的类似限制是 判断不切实际,因为在超类中添加了一个成员 可能导致子类必须重命名局部变量。有关 考虑因素限制局部变量的阴影 嵌套类的成员,或本地变量的局部变量的阴影 在嵌套类中声明的变量也没有吸引力。
这实际上意味着以下代码是合法的:
class A {
int x = 0;
void m() {
int x = 10; // Shadows this.x
}
}
正如作者所描述的那样,允许通过声明一个具有相同名称的方法局部变量来影响实例变量,因为有些人可能会在某一天无法再编译时扩展A
的功能如果阴影是非法的,则为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;
}
由于变量阴影,此程序不易遵循,因此可能无法产生您期望的结果。
答案 1 :(得分:6)
Java不允许您在两个范围内具有相同名称的两个变量。
在你的第二个案例中:
int a = 2;
{
// the outer 'a' is still in scope
int a = 3; // so this is a redeclare <-- nooo!
}
但是,在第一种情况下,每个a
都包含在自己的范围内,所以一切都很好。
答案 2 :(得分:4)
因为在第二种情况下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
}
}
答案 3 :(得分:1)
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!
}
}
在上面的示例中,您在方法a
中声明了main()
。从声明到方法结束,声明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!
}
}
答案 4 :(得分:-4)
在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;
}
}
}
希望这可以帮到你
由于