关于java中变量范围和阴影的问题
我遇到这种情况我无法理解阴影。 例如以下代码
class Foo { int a = 5; void goFoo(int a) { // No problem naming parameter as same as instance variable for (int a = 0; a < 5; a++) { } //Now the compiler complains about the variable a on the for loop // i thought that the loop block had its own scope so i could shadow // the parameter, why the compiler didnt throw an error when i named // the parameter same as the instance variable? } }
谢谢你耐心等待。
您可以使局部变量阴影成为实例/静态变量 – 但是您不能使一个局部变量(您的循环计数器)影响另一个局部变量或参数(您的参数)。
从Java语言规范, 第14.4.3节 :
如果声明为局部变量的名称已经声明为字段名称,那么该外部声明将在局部变量的整个范围内被遮蔽(第6.3.1节)。
注意“字段名称”部分 – 它指定它必须是一个被遮蔽的字段 。
从第8.4.1节开始 :
方法(第8.4.1节)或构造函数(第8.8.1节)的参数范围是方法或构造函数的整个主体。
这些参数名称不能重新声明为方法的局部变量,也不能重新声明为方法或构造函数的try语句中的catch子句的exception参数。
(它继续讨论本地类和匿名类,但它们与你的情况无关。)
void goFoo(int a) { for (int a = 0; a < 5; a++) { } }
它类似于
void goFoo() { int a; for (int a = 0; a < 5; a++) { } }
所以在同一范围内多次声明a
,这是不可接受的。
或者只是它类似于
void goFoo() { int a; int a; }
另见
- java的可变范围,遮蔽
变量的范围也取决于块的层次结构。
即如果你这样使用
void goFoo(int a) { // No problem naming parameter as same as instance variable for (int b = 0; b < 5; b++) { } //Now the compiler complains about the variable a on the for loop // i thought that the loop block had its own scope so i could shadow // the parameter, why the compiler didnt throw an error when i named // the parameter same as the instance variable? int b; // you can do this. }
也就是说,如果在外部块中声明了变量,那么就不能在内部的块中声明相同的内容。 另一种方式你可以做到这一点。
但是,如您的代码所示,您不会在该新范围中声明第二个“a”。 它位于goFoo()块本身的范围内。
问题不在于循环正在遮蔽类字段,该名称已被参数使用。
两个选项:一个是改变循环:
for (a = 0; a < 5; a++) { }
这使用参数作为索引变量。 不清楚为什么你会有一个参数,但都是一样的......
另一个选项是将循环变量或参数重命名为其他内容。
这不是影子,这是一场冲突。 两者都在方法范围内。 无法在同一范围内定义两个同名变量。