我收到以下代码的编译错误:
if(true)
int a = 10;
else
int b = 20;
如果我将其更改为以下代码,则没有编译错误:
if(true) {
int a = 10;
}
else {
int b = 20;
}
为什么第一种语法错误,而且语言标准是什么?
答案 0 :(得分:27)
Java规范说if-then-else
语句具有以下形式:
IfThenElseStatement:
if ( Expression ) StatementNoShortIf else Statement
Statement
和StatementNoShortIf
可以是各种各样的东西,包括块(用大括号括起来的代码),赋值(已经声明的变量),其他if语句等。
值得注意的是,该列表中缺少声明语句(例如int a;
或int a = 10;
),因此会出现编译错误。
有关完整列表,您可以在此处阅读Java规范: http://docs.oracle.com/javase/specs/
答案 1 :(得分:19)
让我们分析一下您的第一个代码示例对语言设计意味着什么
if(condition)
int a = 10;
else
int b = 20;
这意味着我们已根据条件定义了a
或b
。由于我们不知道采用了哪个分支,我们如何在if语句之后使用a
或b
?我们不能(如果可能,那可能会导致奇怪的错误)。
因此,作为语言设计师,我们认为a
和b
在各自的分支之外是不可见的,以避免这些奇怪的错误。但是由于无块分支只能有一个语句,我们已经声明a
(或b
)只能立即无法访问/不可用,所以这样做是没有意义的。因此,我们决定只允许使用块进行变量声明。一个块可以有多个语句,因此该块中声明的变量可以被其他语句使用。
Java的设计者可能应用了类似的推理,因此他们决定只允许在块中声明。这是通过if
(JLS 14.9):
IfThenStatement:
if ( Expression ) Statement
IfThenElseStatement:
if ( Expression ) StatementNoShortIf else Statement
IfThenElseStatementNoShortIf:
if ( Expression ) StatementNoShortIf else StatementNoShortIf
Statement
(JLS 14.5)
Statement:
StatementWithoutTrailingSubstatement
...
StatementNoShortIf:
StatementWithoutTrailingSubstatement
...
StatementWithoutTrailingSubstatement:
Block
...
Block
(JLS 14.2):
Block:
{ [BlockStatements] }
BlockStatements:
BlockStatement {BlockStatement}
BlockStatement:
LocalVariableDeclarationStatement
ClassDeclaration
Statement
LocalVariableDeclarationStatement
(JLS 14.4),重复它只能在一个直接封闭的区块内发生:
每个局部变量声明语句都会立即被一个块包含。局部变量声明语句可以与块中的其他类型的语句自由混合。
答案 2 :(得分:13)
JLS-14.4. Local Variable Declaration Statements读取(部分),
每个局部变量声明语句都会立即被一个块包含。
和
否则,继续执行,根据结果值进行选择:
如果值为true,则执行包含的Statement;当且仅当Statement的执行正常完成时,if-then语句才正常完成。
如果值为false,则不执行进一步操作,if-then语句正常完成。
但是,JLS-14.5. Statements不包含变量声明。
在单语句块(仅包含变量定义)的范围内定义两个不同的变量使它们都无法访问。我认为你在三元表达方面有更好的运气
int a = (condition) ? 10 : 20;
或强>
int a;
if (condition)
a = 10;
else
a = 20;
或强>
int a;
if (condition) {
a = 10;
} else {
a = 20;
}
请注意,变量a
然后被初始化为基于condition
的值,并且在该语句之后可以访问。
答案 3 :(得分:6)
每个局部变量声明语句都会立即被一个块包含。局部变量声明语句可以与块中的其他类型的语句自由混合。
阅读本文 http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.4
答案 4 :(得分:0)
我最好的猜测是你不能有条件地声明变量。