if语句中的Java变量作用域
我收到以下代码的编译错误:if语句中的Java变量作用域,java,syntax-error,Java,Syntax Error,我收到以下代码的编译错误: if(true) int a = 10; else int b = 20; 如果我将其更改为以下代码,则不会出现编译错误: if(true) { int a = 10; } else { int b = 20; } 为什么第一个语法是错误的,来自哪种语言标准 每个局部变量声明语句都立即包含在一个块中。局部变量声明语句可以与块中其他类型的语句自由混合 读这个 我的猜测是,您不能有条件地声明变量 如果没有大括号,则尝试在外部范围内有条
if(true)
int a = 10;
else
int b = 20;
如果我将其更改为以下代码,则不会出现编译错误:
if(true) {
int a = 10;
}
else {
int b = 20;
}
为什么第一个语法是错误的,来自哪种语言标准
每个局部变量声明语句都立即包含在一个块中。局部变量声明语句可以与块中其他类型的语句自由混合
读这个
我的猜测是,您不能有条件地声明变量
- 如果没有大括号,则尝试在外部范围内有条件地声明变量,这是不允许的
- 添加大括号时,您正在该局部范围内创建变量(不允许在这些大括号之外使用)
- 读取(部分)
每个局部变量声明语句都立即包含在一个块中
及
否则,通过基于结果值进行选择继续执行:
如果该值为true,则执行包含的语句;当且仅当语句的执行正常完成时,if-then语句才会正常完成
如果该值为false,则不采取进一步的操作,If-then语句正常完成
但是,不包括变量声明
在单个语句块的范围内定义两个不同的变量(仅包含变量定义)会使它们都无法访问。我想你最好用三元表达式
int a = (condition) ? 10 : 20;
或
int a;
if (condition)
a = 10;
else
a = 20;
int a;
if (condition) {
a = 10;
} else {
a = 20;
}
或
int a;
if (condition)
a = 10;
else
a = 20;
int a;
if (condition) {
a = 10;
} else {
a = 20;
}
请注意,变量
a
随后根据条件初始化为一个值,并且在该语句之后可以访问该值。Java规范规定if-then-else
语句的形式如下:
IfThenElseStatement:
if ( Expression ) StatementNoShortIf else Statement
其中语句
和语句noshortif
可以是各种内容,包括块(用大括号括起来的代码)、赋值(对已声明的变量)、其他if语句等
需要注意的是,该列表中缺少声明语句(例如inta;
或inta=10;
),因此会出现编译错误
有关完整列表,您可以在此处阅读Java规范:
让我们分析第一个代码示例对语言设计的意义
if(condition)
int a = 10;
else
int b = 20;
这意味着取决于我们定义的条件a
或b
。由于我们不知道采用了哪个分支,我们如何在if语句之后使用a
或b
?我们不能(如果我们可以,可能会导致奇怪的错误)
因此,作为语言设计者,我们决定a
和b
在各自的分支之外不可见,以避免这些奇怪的错误。但是,由于无块分支只能有一条语句,因此我们声明a
(或b
)只是立即无法访问/再次无法使用,因此这样做毫无意义。因此,我们决定只允许对块进行变量声明。一个块可以有多个语句,所以在该块中声明的变量可以被其他语句使用
Java的设计者可能应用了类似的推理,所以他们决定只允许在块中声明。这是通过定义if
():
语句
()
块
():
和LocalVariableDeclarationStatement
(),重复它只能出现在一个立即封闭的块中:
每个局部变量声明语句都立即包含在一个块中。局部变量声明语句可以与块中其他类型的语句自由混合
在做了一些测试之后,JVM似乎不喜欢在没有大括号的if-else
中有变量声明。我相信有人可以对此进行更深入的研究,但我猜范围无法解决System.out.println()
在没有大括号的情况下工作。@DrewKennedy如果不允许在中声明变量,那就不会太疯狂了。你设置了一个永远不能使用的变量。@Daniel我也这么想。如果在If
后面只允许有一行代码,那么声明一个变量就没有意义了。@almasshaikh:这看起来不像是一个复制品。这可能类似,但保持if
和for
的语义不同是有意义的。@Daniel,这是因为JavaScript没有块作用域,并且应用变量提升。除了第二个版本compile@JuanMendes第二个版本立即包含在一个块中reason@MarkRotteveel我想我的问题是:第一个不是也包含在一个块中(在if之外)?@JuanMendes不,不是立即。请参阅or,其中对其进行了更详细的描述。我不同意您的评估“因此您的第一个示例为int a创建了一个块,该块终止if块(因此您的else没有匹配的if)。”原因是JLS@MarkRotteveel这是对的。该错误与其他
无关。如果取出else
零件,仍然会出现错误。@标记已编辑。谢谢你的意见,你认为现在读起来更好吗?如果允许的话,你会如何达到目的?因此,我想,为什么它是不被允许的;我从语法的角度看得太多了,而不是从语法的原因。我知道这可能不准确,我希望有人能解释一下答案的问题所在。这个答案对我很有帮助。我想你的猜测只是。。。。你知道的。。。猜测。其他答案提供了文件和这种行为的确切“原因”。@AlessandroDaRugna和你的评论没有解释t
Block:
{ [BlockStatements] }
BlockStatements:
BlockStatement {BlockStatement}
BlockStatement:
LocalVariableDeclarationStatement
ClassDeclaration
Statement