Un bucle de una sola línea con un par obligatorio de llaves en Java

El código en el siguiente fragmento funciona bien. Cuenta el número de objetos creados usando un campo estático de tipo int que es 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"); } } 

Muestra la siguiente salida.

 Number of objects created : 10 

La única pregunta es que cuando elimino el par de llaves del bucle for anterior (vea el bucle comentado), se emite un error en tiempo de comstackción indicando

no es una statement.

¿Por qué en esta situación particular, un par de llaves es obligatorio aunque el ciclo contenga solo una statement ?

Cuando declaras una variable ( main en este caso):

 Main main = new Main(); 

no cuenta como una statement, incluso si tiene efectos secundarios. Para que sea una statement adecuada, solo debes hacer

 new Main(); 

¿Entonces por qué?

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

¿permitido? { ... } es un bloque de código, y cuenta como una statement. En este caso, la variable main podría utilizarse después de la statement, pero antes de la llave de cierre. Algunos comstackdores ignoran el hecho de que de hecho no se usa, otros comstackdores emiten advertencias con respecto a esto.

Puede tener sentido crear un bloque de una línea con una nueva instrucción. Lo que no tiene sentido es guardar una referencia a un objeto recién creado dentro de un bloque de una línea, porque no puede acceder a la variable principal desde fuera del ámbito.

Quizás (solo mi suposición) el comstackdor te obliga a escribir los corchetes explícitamente porque mantener una referencia no tiene sentido en ese caso, con la esperanza de que te des cuenta de la referencia inútil.

for se define de la siguiente manera.

 BasicForStatement: for ( ForInitopt ; Expressionopt ; ForUpdateopt ) Statement ForStatementNoShortIf: for ( ForInitopt ; Expressionopt ; ForUpdateopt ) StatementNoShortIf ForInit: StatementExpressionList LocalVariableDeclaration ForUpdate: StatementExpressionList StatementExpressionList: StatementExpression StatementExpressionList , StatementExpression 

Los bloques se definen de la siguiente manera.

Un bloque es una secuencia de declaraciones, declaraciones de clases locales y declaraciones de declaraciones de variables locales dentro de llaves.

 Block: { BlockStatementsopt } BlockStatements: BlockStatement BlockStatements BlockStatement BlockStatement: LocalVariableDeclarationStatement ClassDeclaration Statement 

Las declaraciones se definen de la siguiente manera.

 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 

De acuerdo con la especificación, LocalVariableDeclarationStatement (mira la sección del bloque) no es válida, si no está declarada dentro de un bloque. Por lo tanto, lo siguiente for bucle informa un error en tiempo de comstackción ” no una statement ” como mencionó en su pregunta a menos que use un par de llaves.

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