Tiny
Tiny

Reputation: 27899

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

The code in the following snippet works just fine. It counts the number of objects created using a static field of type int which is cnt.

public class Main
{
    private static int cnt;

    public Main()
    {
        ++cnt;
    }

    public static void main(String[] args)
    {
        for (int a=0;a<10;a++)
        {
            Main main=new Main();
        }

        /*for (int a=0;a<10;a++)
            Main main=new Main();*/

        System.out.println("Number of objects created : "+cnt+"\n\n");
    }
}

It displays the following output.

Number of objects created : 10

The only question is that when I remove the pair of curly braces from the above for loop (see the commented for loop), a compile-time error is issued indicating

not a statement.

Why in this particular situation, a pair of braces is mandatory even though the loop contains only a single statement?

Upvotes: 23

Views: 5718

Answers (3)

Lion
Lion

Reputation: 19027

for is defined as follows.

BasicForStatement:
    for ( ForInitopt ; Expressionopt ; ForUpdateopt ) Statement

ForStatementNoShortIf:
    for ( ForInitopt ; Expressionopt ; ForUpdateopt ) StatementNoShortIf

ForInit:
    StatementExpressionList
    LocalVariableDeclaration

ForUpdate:
    StatementExpressionList

StatementExpressionList:
    StatementExpression
    StatementExpressionList , StatementExpression

Blocks are defined as follows.

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

Statements are defined as follows.

Statement:
    StatementWithoutTrailingSubstatement
    LabeledStatement
    IfThenStatement
    IfThenElseStatement
    WhileStatement
    ForStatement

StatementWithoutTrailingSubstatement:
    Block
    EmptyStatement
    ExpressionStatement
    AssertStatement
    SwitchStatement
    DoStatement
    BreakStatement
    ContinueStatement
    ReturnStatement
    SynchronizedStatement
    ThrowStatement
    TryStatement

StatementNoShortIf:
    StatementWithoutTrailingSubstatement
    LabeledStatementNoShortIf
    IfThenElseStatementNoShortIf
    WhileStatementNoShortIf
    ForStatementNoShortIf

According to the specification, LocalVariableDeclarationStatement (look at the block section) is invalid, if it's not declared within a block. Therefore, the following for loop reports a compile-time error "not a statement" as you mentioned in your question unless you use a pair of braces.

for (int a=0;a<10;a++)
        Main main=new Main();

Upvotes: 3

enTropy
enTropy

Reputation: 621

It can make sense to create a one-line block with a new statement. What doesn't make sense is to save a reference to a just created object inside a one-line block, because you can't access variable main from outside the for scope.

Perhaps (just my guess) the compiler forces you to type the brackets explicitly because holding a reference doesn't make sense in that case, with the hope you become aware of the useless reference.

Upvotes: 3

aioobe
aioobe

Reputation: 421020

When you declare a variable (main in this case):

Main main = new Main();

it doesn't count as a statement, even if it has side-effects. For it to be a proper statement, you should just do

new Main();

So why is

... {
    Main main = new Main();
}

allowed? { ... } is a block of code, and does count as a statement. In this case the main variable could be used after the declaration, but before the closing brace. Some compilers ignore the fact that it's indeed not used, other compilers emit warnings regarding this.

Upvotes: 28

Related Questions