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

Оператор создания объекта в Java не позволяет использовать однострочный цикл. Зачем?

Следующая программа не имеет значения. Он просто подсчитывает количество объектов, созданных с помощью цикла for, используя статическое поле внутри класса Counter, как показано ниже.

package temp;

final class Counter
{
    private static int cnt;

    public Counter()
    {
        cnt++;
    }

    public static int show()
    {
        return(cnt);
    }
}

final public class Main
{
    public static void main(String[] args)
    {
        for (int i=0;i<50;i++)
        {
            Counter counter=new Counter();
        }

        /*for (int i=0;i<50;i++)
            Counter counter=new Counter();*/

        System.out.print("\nNumber of objects constructed:->"+Counter.show()+"\n\n");
    }
}

Единственный вопрос здесь в том, что запрошенный цикл означает то же самое, что и выше для цикла (то же самое относится и к циклу while) не работает вообще, вызывая ошибку времени компиляции, которая указывает, что "нет утверждение" означает, что в этой конкретной ситуации пара фигурных скобок является обязательной, хотя цикл for содержит только одно утверждение! Почему?

4b9b3361

Ответ 1

Чтобы понять, почему это происходит, вы должны смотреть на синтаксис Java Blocks and Statement в спецификации языка.

A ForStatement определяется как:

ForStatement:
    for ( ForInitopt ; Expressionopt ; ForUpdateopt )
        Statement

Оператор определяется как:

Statement:
    StatementWithoutTrailingSubstatement
    LabeledStatement
    IfThenStatement
    IfThenElseStatement
    WhileStatement
    ForStatement

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

Затем, глядя на блок:

Block:
    { BlockStatementsopt }

BlockStatements:
    BlockStatement
    BlockStatements BlockStatement

BlockStatement:
    LocalVariableDeclarationStatement
    ClassDeclaration
    Statement

Вы заметите, что в этой спецификации LocalVariableDeclarationStatement недействителен, если он не находится в блоке. Но, поскольку ForStatement требует, чтобы за ним последовал оператор, там ДОЛЖЕН существовать круглые скобки, чтобы сделать выражение действительным. Таким образом, любое объявление локальной переменной было бы недопустимым в цикле без скобок.

Ответ 2

Потому что вы создаете переменную области видимости. Java говорит вам, что это ничего не делает, потому что все, что он делает, - это выделить память, и как только цикл пройдет снова, вы потеряете это и сделаете новый. По сути, весь цикл является NOP, поэтому он говорит вам, что он сводится к инструкции do do.

Если цикл является NOP, я имею в виду, что объявление в цикле является NOP.

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

Ответ 3

@JasCav прав, однако вы можете получить его для компиляции:

for (int i=0;i<50;i++)
    new Counter();

Ответ 4

Вы также можете заставить его работать без брекетов таким образом:

Counter counter;
    for (int i = 0; i < 50; i++)
    counter = new Counter();

Не то, чтобы какая-то причина, по которой вы когда-либо хотели бы сделать такое. Оставив скобки, это действительно плохая идея, потому что добавление оператора фактически изменяет поток управления.