Однострочный цикл с обязательной парой фигурных скобок в Java
Код в следующем фрагменте отлично работает. Он подсчитывает количество объектов, созданных с использованием статического поля типа int
, которое 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");
}
}
Он отображает следующий вывод.
Number of objects created : 10
Единственный вопрос заключается в том, что, когда я удаляю пару фигурных скобок из вышеперечисленного цикла for
(см. прокомментированный цикл for
), выдается ошибка времени компиляции с указанием
не утверждение.
Почему в этой конкретной ситуации пара фигурных скобок обязательна, хотя цикл содержит только один оператор?
Ответы
Ответ 1
Когда вы объявляете переменную (main
в этом случае):
Main main = new Main();
он не считается утверждением, даже если он имеет побочные эффекты. Чтобы это было правильное утверждение, вы должны просто сделать
new Main();
Итак, почему
... {
Main main = new Main();
}
разрешено? { ... }
является блоком кода и считается счетчиком. В этом случае переменная main
может быть использована после объявления, но перед закрывающей скобкой. Некоторые компиляторы игнорируют тот факт, что он действительно не используется, другие компиляторы выдают предупреждения об этом.
Ответ 2
Может возникнуть смысл создать однострочный блок с новым выражением. Не имеет смысла сохранять ссылку на только что созданный объект внутри однострочного блока, потому что вы не можете получить доступ к главной переменной из-за пределов области.
Возможно (просто мое предположение) компилятор заставляет вас вводить скобки явно, потому что в этом случае не имеет смысла ссылаться на ссылку, надеясь, что вам станет известно о бесполезной ссылке.
Ответ 3
for
определяется следующим образом.
BasicForStatement:
for ( ForInitopt ; Expressionopt ; ForUpdateopt ) Statement
ForStatementNoShortIf:
for ( ForInitopt ; Expressionopt ; ForUpdateopt ) StatementNoShortIf
ForInit:
StatementExpressionList
LocalVariableDeclaration
ForUpdate:
StatementExpressionList
StatementExpressionList:
StatementExpression
StatementExpressionList , StatementExpression
Блоки определяются следующим образом.
Блок представляет собой последовательность операторов, локальных деклараций классов и локальные инструкции объявления переменных в фигурных скобках.
Block:
{ BlockStatementsopt }
BlockStatements:
BlockStatement
BlockStatements BlockStatement
BlockStatement:
LocalVariableDeclarationStatement
ClassDeclaration
Statement
Заявления определяются следующим образом.
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
В соответствии со спецификацией LocalVariableDeclarationStatement
(смотрите раздел блока) является недопустимым, если он не объявлен в блоке. Поэтому следующий цикл for
сообщает ошибку времени компиляции "не утверждение", как вы упомянули в своем вопросе, если вы не используете пару фигурных скобок.
for (int a=0;a<10;a++)
Main main=new Main();