Pao*_*olo 13 java scope compiler-errors
这将编译
class X
{
public static void main(String args[])
{
{
int a = 2;
}
{
int a = 3;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这不会
class X
{
public static void main(String args[])
{
int a = 2;
{
int a = 3;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我期望两者都编译(也许这是C的工作方式?).原因是什么,因为无法在外部块中使用相同名称的块声明变量?
Raf*_*ter 15
简短的回答是:因为这是JLS§6.4中定义Java语言的方式.
您可能会在其他语言中使用这种所谓的变量阴影.然而,Java语言的发明者认为这是一个他们不想用他们的语言的尴尬功能:
此限制有助于检测一些非常模糊的错误.
但是,您可以在Java的其他位置找到阴影,因为作者在JLS的同一部分中声明:
对局部变量对成员进行阴影的类似限制被认为是不切实际的,因为在超类中添加成员可能导致子类必须重命名局部变量.相关注意事项限制了嵌套类成员对局部变量的阴影,或者对嵌套类中声明的局部变量的局部变量的阴影也没有吸引力.
这实际上意味着以下代码是合法的:
class A {
int x = 0;
void m() {
int x = 10; // Shadows this.x
}
}
Run Code Online (Sandbox Code Playgroud)
正如作者所描述的那样,允许通过声明一个具有相同名称的方法局部变量来遮蔽实例变量,因为有人A可能会在某一天扩展功能,B如果阴影是非法的,则无法再编译一个类:
class B extends A {
void m() {
int x = 10; // Shadows A.this.x if A declares x
}
}
Run Code Online (Sandbox Code Playgroud)
如果你考虑像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;
}
Run Code Online (Sandbox Code Playgroud)
由于变量阴影,该程序不易遵循,因此可能无法产生您期望的结果.
Java不允许您在两个相同的范围内拥有两个相同名称的变量.
在你的第二种情况:
int a = 2;
{
// the outer 'a' is still in scope
int a = 3; // so this is a redeclare <-- nooo!
}
Run Code Online (Sandbox Code Playgroud)
但是,在您的第一种情况下,每个a都包含在自己的范围内,所以一切都很好.
| 归档时间: |
|
| 查看次数: |
9920 次 |
| 最近记录: |