简短的回答是:因为这是 Java 语言的定义方式JLS §6.4 http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.4.
您可能会从其他语言中使用这所谓的可变阴影 http://en.wikipedia.org/wiki/Variable_shadowing被允许。然而,Java 语言的发明者认为这是一个尴尬的功能,他们不希望在他们的语言中出现这样的功能:
此限制有助于检测一些原本非常隐蔽的错误。
然而,正如作者在 JLS 的同一部分中所述,您会在 Java 的其他地方发现影子:
对局部变量遮蔽成员的类似限制是
被认为不切实际,因为在超类中添加成员
可能会导致子类必须重命名局部变量。有关的
考虑因素对局部变量的遮蔽进行了限制
嵌套类的成员,或局部变量的遮蔽
在嵌套类中声明的变量也没有吸引力。
这意味着实际上以下代码是合法的:
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;
}
该程序不太容易遵循,因此由于变量阴影,可能不会产生您期望的结果。