Why can't I define a variable inside a for loo

2019-02-16 09:36发布

问题:

This question already has an answer here:

  • A single-line loop with a mandatory pair of braces in Java 3 answers

Through a test I found out that,

This is not legal :

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

but this is :

for (int i= 0; i < 1000000000; i++) { 
    int j = i & i+1 ;
}

Why?

回答1:

The first way is not legal, as it is clear to the compiler that you can't use j that you declared there, as you can't have another statement inside that for loop. Basically the new declaration of variable at that place will go out of scope the very next statement, thus is not doing any good.

While in the second case, the loop is followed by braces, which creates a new scope, and you can use the variable.



回答2:

A local variable declaration needs to be in a block. In the first case, you don't have it in a block. In the second case, j is within a block, so it is legal.

The local variable declaration isn't a statement, it is a local variable declaration statement. From the reference below, a local variable declaration can appear only as a statement within a block. (A block is a pair of curly braces containing statements and declarations.)

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
}

Quoting from 14.4. Local Variable Declaration Statements:

...

Every local variable declaration statement is immediately contained by a block. Local variable declaration statements may be intermixed freely with other kinds of statements in the block.

...

And from 14.2. Blocks:

A block is a sequence of statements, local class declarations, and local variable declaration statements within braces.

 Block:
   { BlockStatementsopt }

 BlockStatements:
   BlockStatement
   BlockStatements BlockStatement

 BlockStatement:
   LocalVariableDeclarationStatement
   ClassDeclaration
   Statement

A block is executed by executing each of the local variable declaration statements and other statements in order from first to last (left to right). If all of these block statements complete normally, then the block completes normally. If any of these block statements complete abruptly for any reason, then the block completes abruptly for the same reason.


Moreover, this behavior isn't quite limited to Java. You'd observe an error in a similar situation even in 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 */
}


回答3:

A local variable declaration isn't allowed as a single statement for any of the grammatical constructs that allow for a single statement instead of a block. So for, while, if, etc...

The way it breaks down is (paraphrased a bit), you have the for statement:

for ( ... ; ... ; ... ) Statement

Where Statement can include:

  • Block

  • ExpressionStatement

An ExpressionStatement is what you can use when you only have the single statement but a LocalVariableDeclarationStatement is only a BlockStatement.

As @RohitJain has pointed out it wouldn't be particularly useful to only have a variable declaration as the single statement of a loop.