开发者

Why is it not possible to shadow a local variable in a loop?

开发者 https://www.devze.com 2023-02-03 12:57 出处:网络
I got this situation I can\'t understand about shadowing. For example the following code: class Foo { int a = 5;

I got this situation I can't understand about shadowing. For example the following code:

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 it开发者_如何学运维s own scope so I could shadow
       // the parameter, why the compiler didn't throw an error when i named
       // the parameter same as the instance variable?
   }
}


You can make a local variable shadow an instance/static variable - but you can't make one local variable (your loop counter) shadow another local variable or parameter (your parameter).

From the Java Language Specification, section 14.4.3:

If a name declared as a local variable is already declared as a field name, then that outer declaration is shadowed (§6.3.1) throughout the scope of the local variable.

Note the "field name" part - it's specifying that it has to be a field that is shadowed.

And from section 8.4.1:

The scope of a parameter of a method (§8.4.1) or constructor (§8.8.1) is the entire body of the method or constructor.

These parameter names may not be redeclared as local variables of the method, or as exception parameters of catch clauses in a try statement of the method or constructor.

(It goes on to talk about local classes and anonymous classes, but they're irrelevant in your case.)


void goFoo(int a) { 

       for (int a = 0; a < 5; a++) { }

}

it is similar to

void goFoo() { 
       int a;
       for (int a = 0; a < 5; a++) { }

}

so multiple declaration of a on the same scope, it is not acceptable.

or simply it is similar to

void goFoo() { 
  int a;
  int a;
} 

Also See

  • java-variable-scope-shadowing


The scope of the variable depends on the hierarchy of the block as well.

ie if u use like this

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.

   }

That is if a variable is declared in the outer block then you can not declare the same in the block which is inner. the other way you can do it.


But you don't declare the second "a" in that new scope, as your code shows. It's in the scope of the goFoo() block itself.


The problem isn't that the loop is shadowing the class field, the name is already used by the parameter.

Two options: One is to change the loop:

for (a = 0; a < 5; a++) { }

This uses the parameter as the index variable. Not clear why you would have a parameter, but all the same...

The other option is to rename the loop variable or the parameter to something else.


It is not shadowing, it is a conflict here. Both a are in the method scope. One cannot define two variables of same name in the same scope.


In Java (unlike, say, in c++) you cannot declare a local variable when another local variable with the same name is "in scope".

You cannot do this in 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.
    }
}

However c++ allows you to do this

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

精彩评论

暂无评论...
验证码 换一张
取 消