我遇到这种情况我无法理解阴影。例如以下代码
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?
}
}
谢谢你耐心等待。
答案 0 :(得分:12)
您可以将局部变量阴影设置为实例/静态变量 - 但是您不能使一个局部变量(您的循环计数器)影响另一个局部变量或参数(您的参数)。
来自Java语言规范,section 14.4.3:
如果声明为局部变量的名称已经声明为字段名称,那么该外部声明将在局部变量的整个范围内被遮蔽(第6.3.1节)。
注意“字段名称”部分 - 它指定它必须是被遮蔽的字段。
方法(§8.4.1)或构造函数(§8.8.1)的参数范围是方法或构造函数的整个主体。
这些参数名称不能重新声明为方法的局部变量,也不能重新声明为方法或构造函数的try语句中的catch子句的异常参数。
(继续讨论本地课程和匿名课程,但在你的情况下它们无关紧要。)
答案 1 :(得分:2)
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;
}
另见
答案 2 :(得分:1)
变量的范围也取决于块的层次结构。
即如果你这样使用
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.
}
即如果在外部块中声明了变量,那么就不能在内部的块中声明相同的内容。你能做到的另一种方式。
答案 3 :(得分:0)
但是您没有在代码显示的新范围内声明第二个“a”。它位于goFoo()块本身的范围内。
答案 4 :(得分:0)
问题不在于循环是否遮蔽了类字段,该名称已被参数使用。
两个选项:一个是改变循环:
for (a = 0; a < 5; a++) { }
这使用参数作为索引变量。不清楚为什么你会有一个参数,但都是一样的......
另一个选项是将循环变量或参数重命名为其他内容。
答案 5 :(得分:0)
这不是影子,这是一场冲突。 a
都在方法范围内。无法在同一范围内定义两个具有相同名称的变量。
答案 6 :(得分:0)
在 Java 中(与 C++ 不同),当另一个同名的局部变量在“作用域内”时,您不能声明局部变量。
您不能在 Java 中执行此操作
void foo() {
int a;
{
int a; // You cannot declare 'a' here because a
// from the outer block is still in scope
// here. Local variables in Java cannot be
// shadowed by another local variable with
// the same name. Only instance variables
// can be shadowed by the local variables
// with the same name.
}
}
但是 C++ 允许你这样做
void foo()
{
int a;
a = 10;
cout << a << endl; // prints 10 duh
{
int a; // this declaration shadows the local
// variable 'a' from the outer scope.
a = 20; // assigns 20 to the variable 'a' in
// current inner scope, like you'd expect.
cout << a << endl; // prints 20.
}
cout << a << endl; // prints 10
}