Reputation: 27899
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
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
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
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