23

以下代码段中的代码运行良好。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循环),会发出编译时错误,指示

不是声明。

为什么在这种特殊情况下,即使循环只包含一个语句,一对大括号也是强制性的?

4

3 回答 3

28

当您声明一个变量时(main在这种情况下):

Main main = new Main();

它不算作陈述,即使它有副作用。为了它是一个正确的陈述,你应该这样做

new Main();

那么为什么是

... {
    Main main = new Main();
}

允许吗?{ ... }是一个代码块,并且确实算作一个语句。在这种情况下,main变量可以在声明之后使用,但在右大括号之前。一些编译器忽略了它确实没有被使用的事实,其他编译器对此发出警告。

于 2012-07-22T17:44:12.310 回答
3

使用新语句创建单行块是有意义的。没有意义的是将对刚刚创建的对象的引用保存在一行代码块中,因为您无法从 for 范围之外访问变量 main 。

也许(只是我的猜测)编译器会强制您显式键入括号,因为在这种情况下持有引用没有意义,希望您能意识到无用的引用。

于 2012-07-22T17:56:46.407 回答
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();
于 2012-07-23T19:05:45.403 回答