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のことを示すコンパイル時エラーが発生することです。

声明ではありません。

この特定の状況で、ループにステートメントが 1 つしか含まれていないにもかかわらず、中かっこのペアが必須なのはなぜですか?

4

3 に答える 3

28

変数を宣言する場合 (mainこの場合):

Main main = new Main();

副作用があっても、ステートメントとしてカウントされません。それが適切なステートメントであるためには、次のようにする必要があります

new Main();

ではなぜ

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

許可された?{ ... }はコードのブロックであり、ステートメントとしてカウントされますこの場合、main変数は宣言の後、右中括弧の前に使用できます。実際に使用されていないという事実を無視するコンパイラもあれば、これに関する警告を発するコンパイラもあります。

于 2012-07-22T17:44:12.310 に答える
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ループはコンパイル時エラー「not a statement 」を報告します。

for (int a=0;a<10;a++)
        Main main=new Main();
于 2012-07-23T19:05:45.403 に答える
3

新しいステートメントで 1 行のブロックを作成することは理にかなっています。for スコープの外から変数 main にアクセスできないため、作成したばかりのオブジェクトへの参照を 1 行のブロック内に保存することは意味がありません。

おそらく(私の推測ですが)、コンパイラは括弧を明示的に入力するように強制します。その場合、参照を保持しても意味がないため、役に立たない参照に気付くことを期待しています。

于 2012-07-22T17:56:46.407 に答える