Подтвердить что ты не робот

Однострочный цикл с обязательной парой фигурных скобок в 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), выдается ошибка времени компиляции с указанием

не утверждение.

Почему в этой конкретной ситуации пара фигурных скобок обязательна, хотя цикл содержит только один оператор?

4b9b3361

Ответ 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();