为什么遵循控制结构条件的声明需要在一个块中



尝试编译以下内容时

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;需要位于块中才能编译代码?

为什么 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 生产中。

不能声明局部作用域变量以直接在父作用域中使用它。

当您不放置大括号时,它会导致条件的单个解释语句。

因此,如果此语句是赋值,显然以后将无法使用此赋值,因为只有父作用域(大括号外)是操作它的唯一方法。

因此,编译器抱怨这种情况。

为了避免这种情况并且不添加大括号,您必须执行以下操作:

public void method(String foo) {
        Object bar;
        if(foo instanceof Object)   //redundant here by the way...
          bar = (Object) foo;
          //...
}

最新更新