关于java中变量范围和阴影的问题

时间:2011-01-07 07:19:34

标签: java variables scope shadowing

我遇到这种情况我无法理解阴影。例如以下代码

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?
   }
}

谢谢你耐心等待。

7 个答案:

答案 0 :(得分:12)

您可以将局部变量阴影设置为实例/静态变量 - 但是您不能使一个局部变量(您的循环计数器)影响另一个局部变量或参数(您的参数)。

来自Java语言规范,section 14.4.3

  

如果声明为局部变量的名称已经声明为字段名称,那么该外部声明将在局部变量的整个范围内被遮蔽(第6.3.1节)。

注意“字段名称”部分 - 它指定它必须是被遮蔽的字段

来自section 8.4.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
}
相关问题