Оператор создания объекта в 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 содержит только одно утверждение! Почему?
Ответы
Ответ 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();
Не то, чтобы какая-то причина, по которой вы когда-либо хотели бы сделать такое.
Оставив скобки, это действительно плохая идея, потому что добавление оператора фактически изменяет поток управления.