Java中的对象创建语句不允许使用单行循环。 为什么?

以下程序没有自己的重要性。 它只使用类Counter中的静态字段计算通过使用for循环创建的对象数,如下所示。

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"+Counter.show()+"\n\n"); } } 

这里唯一的问题是注释for循环意味着与上面的for循环相同(同样的东西也应用于while循环)根本不起作用导致编译时错误,表明“ 不是语句 ”意味着在这种特殊情况下,即使for循环只包含一个语句,这对括号也是必需的! 为什么?

要理解为什么会发生这种情况,您必须查看语言规范中的Java的Blocks和Statements语法 。

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:

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

您会注意到,在此规范中,LocalVariableDeclarationStatement无效,除非它在块中。 但是,因为ForStatement要求它后跟一个语句,所以必须存在括号以使表达式有效。 因此,任何局部变量声明在没有括号的循环中都是无效的。

因为您正在创建范围变量。 Java告诉你这没有任何作用,因为它所做的就是分配内存,一旦循环再次通过,你就会失去那个并创建一个新内存。 从本质上讲,整个循环是一个NOP,这就是为什么它告诉你它减少为无所作为的声明。

循环是NOP我的意思是循环中的声明是NOP。

带有大括号的版本的原因是因为编译器没有检查范围内的用法,因为有大括号。 这可能与从一行语句生成的解析树与在有完整循环范围时创建的解析树有关。

您也可以通过这种方式使其无需支撑:

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

并不是说你有任何理由想做这样的事情。 离开括号是一个非常糟糕的主意,因为添加一个语句实际上会使控制流发生变化。

@JasCav是对的,但你可以编译它:

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