为什么我们不能在 if 语句后面定义变量?

4
public class Foo{    
  public static void main(String []args){  
    int a=10;
    if(a==10)
    int x=20;    
  }
}

在编译上述代码时会出现错误。

但是,在下面的代码中却没有问题。为什么呢?

public class Foo{    
  public static void main(String []args){    
    int a=10;    
    if(a==10){    
    int x=20;
    }
  }
}

我不理解,这些代码到底在发生什么?按照我的理解,我们可以在if语句后面写一个语句而无需使用大括号(语句块)。

1
在编译时添加你所遇到的错误信息。 - Nir Levy
你的代码看起来没问题,具体是哪里出错了? - Owen James
Foo.java:9: 错误:不是语句 int x=20;
^ Foo.java:9: 错误:表达式开始非法 int x=20; ^
- Vaibhav Shahapure
1
@VaibhavShahapure:为了改进一个问题,请使用“编辑”链接而不是评论。 - T.J. Crowder
1
这是一个好问题...不知道为什么被踩了... - Codebender
2个回答

13

为了清晰明确,问题在这里:

if(a==10)
    int x=20;

...而错误是error: variable declaration not allowed here

之所以不允许在那里声明变量,是因为在if后面只有特定的语句列表才被允许;它们在JLS§14.5中详细说明:

  • StatementWithoutTrailingSubstatement
  • LabeledStatement
  • IfThenStatement
  • IfThenElseStatement
  • WhileStatement
  • ForStatement

StatementWithoutTrailingSubstatement (上面的第一条)包括以下内容:

  • Block
  • EmptyStatement
  • ExpressionStatement
  • AssertStatement
  • SwitchStatement
  • DoStatement
  • BreakStatement
  • ContinueStatement
  • ReturnStatement
  • SynchronizedStatement
  • ThrowStatement
  • TryStatement

请注意,LocalVariableDeclarationStatement 不出现在该列表中。而LocalVariableDeclarationStatement是允许在Block中的,所以您的第二个例子是可以的。

为什么它不在列表中?推测语言设计者为什么做什么总是很危险的。但是无论怎样:假设他们允许了它。这是什么意思?它只被限定在if的主体内吗?那有点毫无意义,不是吗?除了初始化引起的副作用(例如int x = foo();),它没有其他影响,并且在这种情况下,您应该只写引起副作用的内容(foo();)。如果它不仅仅限定在if的主体内(它最终进入包含作用域),那就相当令人困惑,不是吗?它看起来好像只有在if的条件为真时才会声明...


0

好的,首先要格式化您的代码,这样更容易阅读。

我从未尝试过这个。但它绝对没有意义。int x=20是死代码,因为在if语句中没有{ },只允许一个命令。因此,在这个命令中定义了一个变量,紧接着在'if'的上下文中再次未定义,因为'if'的上下文已经离开了。而且'x'只在'if'的上下文中有效。

public class Foo {

    public static void main(String []args){

        int a=10;

        if(a==10)
            int x=20;

    }
}

我猜这段死代码在编译器看来肯定是错误的和无意的。

你的另一个例子也是一样的,但编译器没有注意到它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接