在Java中重新声明循环内的变量

时间:2015-06-16 02:11:16

标签: java loops variables

在Java中,我们不能在具有相同名称的另一个变量的同一范围内声明变量:

int someInteger = 3;

...

int someInteger = 13;

语法错误,不编译。但是,如果我们把它放在一个循环中:

for (int i = 0; i < 10; i++) {
   int someInteger = 3;
}

不会产生错误,效果很好。我们基本上声明了相同的变量。是什么原因?在这背后我不了解/理解的逻辑是什么?

7 个答案:

答案 0 :(得分:9)

想一想,在每次循环之后,范围被“破坏”,变量就消失了。在下一个循环中,将创建一个新范围,并且可以在该范围内再次声明该变量。

出于类似的原因,你也可以这样做

        {
           int someInteger = 3;
        }
        {
           int someInteger = 13;
        }

顺便说一句,Java不允许局部变量阴影,这可能不方便

        int x = 3;
        {
           int x = 13; // error!
        }

        Consumer<Integer> consumer = (x)->print(x);  // ERROR! 
        // lambda parameter is treated like local variable

        Runnable r = ()->{ int x; ... } // ERROR
        // lambda body is treated like local block

答案 1 :(得分:4)

Java具有所谓的“块范围”,这意味着任何代码块(由封闭的花括号定义)声明一个变量,那个(并且只有那里)就是它存在的地方。这也意味着每个变量只能在任何给定的块中声明一次。

当你说

for (int i = 0; i < 10; i++) {
  int someInteger = 3;
}

每次迭代都会创建一个新块。它类似于说

{ 
  int someInteger = 3;
}
{ 
  int someInteger = 3;
}
...

在这种情况下,每个块中只有一个名为someInteger的变量。

当你说

{ 
  int someInteger = 3;
  ...
  int someInteger = 3;
}

编译器正确地抱怨您在相同的代码块(或范围)中声明了多个具有相同名称的变量。

答案 2 :(得分:2)

在一个块的范围内,会创建一个新的someInteger,并且阴影是任何其他someInteger的词法范围。 Variable shadowing上的维基百科条目(部分)

  当在特定范围内声明的变量(决策块,方法或内部类)与在外部范围内声明的变量具有相同的名称时,会发生

变量阴影。在标识符(名称而不是变量)级别,这称为name masking

答案 3 :(得分:2)

每个变量都有一个范围。范围嵌套在括号{}中。当你离开这个范围时,这个上下文消失了,所以你可以定义其他具有相同名称的变量。否则,你不能。

我将举两个例子:

// define new scope named "methodA"
public void methodA() {
   int a = 3; 
   // define new scope named "loop"
   for (int i = 0; i < 10; i++) {
      int a = 6; // ERROR
   }
}

在上述情况下,您将遇到错误。因为&#34;循环&#34;范围在&#34;方法A&#34;范围,所以当你去&#34;循环&#34;时,a的第一个定义仍然存在。范围。

第二种情况:

// define new scope named "methodA"
public void methodA() {
   // define new scope inside methodA scope
   {
       int a = 3;
   } 
   // define new scope named "loop"
   for (int i = 0; i < 10; i++) {
      int a = 6; // NO ERROR
   }
}

上面的代码将成功编译,因为a的第一个定义在a的第二个定义的不同范围内,并且这些范围没有嵌套。

答案 4 :(得分:0)

如果某个类或方法与第一次使用的范围不同,则可以在类或方法中重复使用相同的变量名。

在第一个示例中,两个变量具有相同的范围,因此名称冲突,编译器报告错误。在你的第二个例子中,它们有不同的范围 - 一个在方法中,另一个在for循环中 - 因此没有冲突并且代码编译。

答案 5 :(得分:-1)

不同的范围;

int variables = 3;
....
int variables = 13;

范围一致,肯定编译错误; 但

for (;;;) {
     int variables = 13;
}

每个周期等同于重新建立变量变量变量,然后随着范围的变化而消失; JVM堆栈框架就是这样一种机制(局部变量具有分配过程的开始,随着过程的结束而消除);

答案 6 :(得分:-1)

您可以将变量推送到数组中。

Stack myarr = new Stack();
for (int i = 0; i < 10; i++) {
   int someInteger = 3;
myarr.push(someInteger);
}

或创建一个变量everyloop

for (int i = 0; i < 10; i++) {
   int someInteger+i = 3;
}