为什么不能在循环中隐藏局部变量?

发布于 2024-10-10 11:18:59 字数 505 浏览 4 评论 0原文

我遇到了这种情况,我无法理解阴影。例如下面的代码:

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 didn't throw an error when i named
       // the parameter same as the instance variable?
   }
}

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

甜柠檬 2024-10-17 11:19:00

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

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
}
回心转意 2024-10-17 11:18:59

您可以使局部变量遮蔽实例/静态变量 - 但不能使一个局部变量(您的循环计数器)遮蔽另一个局部变量或参数(您的参数)。

来自 Java 语言规范,第 14.4.3 节< /a>:

如果声明为局部变量的名称已声明为字段名称,则该外部声明在整个局部变量的范围内都会被隐藏(第 6.3.1 节)。

请注意“字段名称”部分 - 它指定它必须是一个被隐藏的字段

以及第 8.4.1 节

方法(第 8.4.1 节)或构造函数(第 8.8.1 节)的参数范围是方法或构造函数的整个主体。

这些参数名称不能重新声明为方法的局部变量,也不能重新声明为方法或构造函数的 try 语句中 catch 子句的异常参数。

(它继续讨论本地类和匿名类,但它们与您的情况无关。)

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.)

风启觞 2024-10-17 11:18:59
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;
} 

另请参阅

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

静谧 2024-10-17 11:18:59

变量的范围也取决于块的层次结构。

即如果你像这样使用

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.

   }

,即如果在外部块中声明了一个变量,那么你不能在内部块中声明相同的变量。你可以用另一种方式做到这一点。

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.

傲性难收 2024-10-17 11:18:59

但是,正如代码所示,您没有在新范围中声明第二个“a”。它位于 goFoo() 块本身的范围内。

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.

維他命╮ 2024-10-17 11:18:59

问题不在于循环遮盖了类字段,而该名称已被参数使用。

两种选择:一是更改循环:

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

这使用参数作为索引变量。不清楚为什么你会有一个参数,但都是一样的......

另一个选项是将循环变量或参数重命名为其他名称。

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.

岁月打碎记忆 2024-10-17 11:18:59

这不是阴影,而是这里的冲突。两个 a 都在方法范围内。不能在同一范围内定义两个同名的变量。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文