为什么我不能以这种方式在for循环中定义变量?

mok*_*mok 13 java for-loop compiler-errors

通过测试,我发现,

这不合法:

for (int i= 0; i < 1000000000; i++) 
    int j = i & i+1 ; // j cannot be declared here!
Run Code Online (Sandbox Code Playgroud)

但这是:

for (int i= 0; i < 1000000000; i++) { 
    int j = i & i+1 ;
}
Run Code Online (Sandbox Code Playgroud)

为什么?

dev*_*ull 17

局部变量声明需要在一个块中.在第一种情况下,您没有在一个块中.在第二种情况下,j是在一个区块内,所以它是合法的.

局部变量声明不是语句,它是局部变量声明语句.从下面的引用中,局部变量声明只能作为块中的语句出现.(块是一对包含语句和声明的花括号.)

for (int i= 0; i < 1000000000; i++) 
    int j = i & i+1 ; // Local variable j declaration not within a block ==> ERROR


for (int i= 0; i < 1000000000; i++) { 
    int j = i & i+1 ; // Local variable j declaration within a block ==> NO ERROR
}
Run Code Online (Sandbox Code Playgroud)

引自14.4.地方变量声明声明:

...

每个局部变量声明语句都立即由一个块包含.局部变量声明语句可以与块中的其他类型的语句自由混合.

...

从14.2开始.块:

块是大括号内的语句,本地类声明和局部变量声明语句的序列.

 Block:
   { BlockStatementsopt }

 BlockStatements:
   BlockStatement
   BlockStatements BlockStatement

 BlockStatement:
   LocalVariableDeclarationStatement
   ClassDeclaration
   Statement
Run Code Online (Sandbox Code Playgroud)

通过从第一个到最后一个(从左到右)按顺序执行每个局部变量声明语句和其他语句来执行块.如果所有这些块语句都正常完成,则块正常完成.如果这些块语句中的任何一个因任何原因突然完成,则块会因同样的原因突然完成.


而且,这种行为并不仅限于Java.即使在C中,您也会在类似情况下发现错误:

for(int i=0; i<=100; i++)
  int j = i;     /* Error: error: expected expression before 'int' */

for(int i=0; i<=100; i++) {
  int j = i;     /* Perfect */
}
Run Code Online (Sandbox Code Playgroud)


Roh*_*ain 12

第一种方法是不合法的,因为编译器很清楚你不能使用j你在那里声明的方法,因为你不能在该for循环中有另一个语句.基本上,在那个地方新的变量声明将超出下一个声明的范围,因此没有任何好处.

在第二种情况下,循环后跟括号,这会创建一个新范围,您可以使用该变量.

  • @Szymon:一个使用花括号,它允许变量的新范围.另一个没有. (3认同)