6

以下をコンパイルしようとすると

public class Test {
    public void method(String foo) {
        // This compiles if the curly braces are uncommented
        if(foo instanceof Object) // {
            Object bar = (Object) foo;
        // }
    }
}

次のエラーが発生します

javac -Xlint:all Test.java
Test.java:5: error: not a statement
            Object bar = foo;
            ^
Test.java:5: error: ';' expected
            Object bar = foo;
                  ^
2 errors

Object bar = (Object) foo;コードをコンパイルするためにブロック内にある必要があるのはなぜですか?

4

2 に答える 2

7

Object bar =(Object)foo;なのはなぜですか。コードをコンパイルするためにブロック内にある必要がありますか?

それがブロック内の唯一のステートメントである場合、変数を宣言することは無意味だからです。後続のコードで変数を参照できないため、宣言は無意味です。(変数のスコープは単なる宣言になります。)

基本的に、コンパイラはあなたが無意味なことをするのを止めています。

仕様に関しては、これはあなたが使用しようとしているプロダクションです(JLSのセクション14.9):

IfThenStatement:
    if ( Expression ) Statement    

これで、ステートメントの生成はセクション14.5で定義されます。

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がないことに注意してください。これは、JLSのセクション14.4で定義されているBlockStatementプロダクションでのみ発生します。

于 2012-11-30T14:48:01.757 に答える
1

親スコープで直接使用するためにローカルスコープ変数を宣言することはできません。

中括弧を配置しない場合、条件の単一の解釈されたステートメントになります。

したがって、このステートメントが割り当てである場合、親スコープ(中括弧の外側)のみがそれを操作するための一意の方法であるため、この割り当てを後で使用することはできません。

したがって、コンパイラはこの状況について不平を言います。

それを回避し、中括弧を付けずに、次のようにする必要があります。

public void method(String foo) {
        Object bar;
        if(foo instanceof Object)   //redundant here by the way...
          bar = (Object) foo;
          //...
}
于 2012-11-30T14:46:04.117 に答える