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

时间:2011-11-16 01:48:40

标签: java

以下程序没有自己的重要性。它只计算使用类计数器内部的静态字段通过使用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<50;i++)
            Counter counter=new Counter();*/

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

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

4 个答案:

答案 0 :(得分:27)

要了解发生这种情况的原因,您必须在语言规范中查看Java's Blocks and Statements syntax

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要求它后跟一个语句,所以必须存在括号以使表达式有效。因此,任何局部变量声明在没有括号的循环中都是无效的。

答案 1 :(得分:6)

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

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

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

答案 2 :(得分:4)

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

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

答案 3 :(得分:4)

你也可以通过这种方式让它无需支撑:

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

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