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    

现在 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 回答