This question already has an answer here:
这个问题在这里已有答案:
- Declaring a useless local variable 2 answers
- A single-line loop with a mandatory pair of braces in Java 3 answers
声明一个无用的局部变量2答案
一个单行循环,在Java 3答案中有一对强制括号
I received a compilation error for the following code:
我收到以下代码的编译错误:
if(true)
int a = 10;
else
int b = 20;
If I change it to the following code, then there is no compilation error:
如果我将其更改为以下代码,则没有编译错误:
if(true) {
int a = 10;
}
else {
int b = 20;
}
Why is the first syntax wrong, and from what language standard?
为什么第一种语法错误,而且语言标准是什么?
5 个解决方案
#1
27
The Java specification says that an if-then-else
statement is of the following form:
Java规范说if-then-else语句具有以下形式:
IfThenElseStatement:
if ( Expression ) StatementNoShortIf else Statement
Where Statement
and StatementNoShortIf
can be various things including blocks (code surrounded with braces), assignments (to already declared variables), other if statements etc.
其中Statement和StatementNoShortIf可以是各种各样的东西,包括块(用大括号括起来的代码),赋值(已经声明的变量),其他if语句等。
Of note is that declaration statements (e.g. int a;
or int a = 10;
) are missing from that list, thus you get a compilation error.
值得注意的是,该列表中缺少声明语句(例如int a;或int a = 10;),因此会出现编译错误。
For the full list, you can read the Java specification here: http://docs.oracle.com/javase/specs/
有关完整列表,您可以在此处阅读Java规范:http://docs.oracle.com/javase/specs/
#2
19
Lets analyze what your first code example would mean for the language design
让我们分析一下您的第一个代码示例对语言设计意味着什么
if(condition)
int a = 10;
else
int b = 20;
Either it means that depending on the condition we have defined a
or b
. As we don't know which branch was taken, how do we use either a
or b
after the if-statement? We can't (and if we could that would probably result in strange bugs).
要么它意味着根据条件我们定义了a或b。由于我们不知道采用了哪个分支,我们如何在if语句后使用a或b?我们不能(如果可能,那可能会导致奇怪的错误)。
So as language designers we decide that a
and b
are not visible outside their respective branches to avoid these weird bugs. But as a block-less branch can only have a single statement, we have declared a
(or b
) only to be immediately unreachable/unusable again, so doing that makes no sense. Therefor we decide that a variable declaration is only allowed with a block. A block can have multiple statements, so variables declared in that block can be used by those other statements.
因此,作为语言设计者,我们认为a和b在各自的分支之外是不可见的,以避免这些奇怪的错误。但是由于无块分支只能有一个语句,我们已经声明一个(或b)只能立即再次无法访问/不可用,所以这样做是没有意义的。因此,我们决定只允许使用块进行变量声明。一个块可以有多个语句,因此该块中声明的变量可以被其他语句使用。
The designers of Java probably applied similar reasoning, so they decided to only allow declaration in a block. This is done through the definition of if
(JLS 14.9):
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)
声明(JLS 14.5)
Statement:
StatementWithoutTrailingSubstatement
...
StatementNoShortIf:
StatementWithoutTrailingSubstatement
...
StatementWithoutTrailingSubstatement:
Block
...
Block
(JLS 14.2):
Block(JLS 14.2):
Block:
{ [BlockStatements] }
BlockStatements:
BlockStatement {BlockStatement}
BlockStatement:
LocalVariableDeclarationStatement
ClassDeclaration
Statement
And LocalVariableDeclarationStatement
(JLS 14.4), which repeats that it can only occur within a immediately enclosing block:
和LocalVariableDeclarationStatement(JLS 14.4),它重复它只能发生在一个直接封闭的块中:
Every local variable declaration statement is immediately contained by a block. Local variable declaration statements may be intermixed freely with other kinds of statements in the block.
每个局部变量声明语句都立即被一个块包含。局部变量声明语句可以与块中的其他类型的语句*混合。
#3
13
JLS-14.4. Local Variable Declaration Statements reads (in part),
JLS-14.4。地方变量声明声明(部分),
Every local variable declaration statement is immediately contained by a block.
每个局部变量声明语句都立即被一个块包含。
And
JLS-14.9。如果是Statmenets
Otherwise, execution continues by making a choice based on the resulting value:
否则,通过根据结果值进行选择继续执行:
If the value is true, then the contained Statement is executed; the if-then statement completes normally if and only if execution of the Statement completes normally.
如果值为true,则执行包含的Statement;当且仅当Statement的执行正常完成时,if-then语句才能正常完成。
If the value is false, no further action is taken and the if-then statement completes normally.
如果值为false,则不执行进一步操作,if-then语句正常完成。
However, JLS-14.5. Statements doesn't include variable declaration.
但是,JLS-14.5。声明不包括变量声明。
Defining two different variables within the scope of a single-statement block (containing just the variable definitions) makes them both unreachable. I think you'd have better luck with a ternary expression
在单语句块(仅包含变量定义)的范围内定义两个不同的变量使它们都无法访问。我觉得你的三元表达会更好运
int a = (condition) ? 10 : 20;
or
int a;
if (condition)
a = 10;
else
a = 20;
or
int a;
if (condition) {
a = 10;
} else {
a = 20;
}
Note that the variable a
is then initialized to a value based on the condition
and it is reachable after that statement.
请注意,变量a然后根据条件初始化为一个值,并且在该语句之后可以访问。
#4
6
Every local variable declaration statement is immediately contained by a block. Local variable declaration statements may be intermixed freely with other kinds of statements in the block.
每个局部变量声明语句都立即被一个块包含。局部变量声明语句可以与块中的其他类型的语句*混合。
Read this http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.4
阅读http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.4
#5
0
My best guess is that you cannot declare variables conditionally.
我最好的猜测是你无法有条件地声明变量。
- When you don't have braces, you're trying to declare a variable conditionally in the outer scope, that's not allowed.
- When you add the braces, you're creating the variables in that local scope (which are not allowed to be used outside of those braces)
当你没有大括号时,你试图在外部范围内有条件地声明一个变量,这是不允许的。
添加大括号时,您将在该局部范围内创建变量(不允许在这些大括号外使用)
#1
27
The Java specification says that an if-then-else
statement is of the following form:
Java规范说if-then-else语句具有以下形式:
IfThenElseStatement:
if ( Expression ) StatementNoShortIf else Statement
Where Statement
and StatementNoShortIf
can be various things including blocks (code surrounded with braces), assignments (to already declared variables), other if statements etc.
其中Statement和StatementNoShortIf可以是各种各样的东西,包括块(用大括号括起来的代码),赋值(已经声明的变量),其他if语句等。
Of note is that declaration statements (e.g. int a;
or int a = 10;
) are missing from that list, thus you get a compilation error.
值得注意的是,该列表中缺少声明语句(例如int a;或int a = 10;),因此会出现编译错误。
For the full list, you can read the Java specification here: http://docs.oracle.com/javase/specs/
有关完整列表,您可以在此处阅读Java规范:http://docs.oracle.com/javase/specs/
#2
19
Lets analyze what your first code example would mean for the language design
让我们分析一下您的第一个代码示例对语言设计意味着什么
if(condition)
int a = 10;
else
int b = 20;
Either it means that depending on the condition we have defined a
or b
. As we don't know which branch was taken, how do we use either a
or b
after the if-statement? We can't (and if we could that would probably result in strange bugs).
要么它意味着根据条件我们定义了a或b。由于我们不知道采用了哪个分支,我们如何在if语句后使用a或b?我们不能(如果可能,那可能会导致奇怪的错误)。
So as language designers we decide that a
and b
are not visible outside their respective branches to avoid these weird bugs. But as a block-less branch can only have a single statement, we have declared a
(or b
) only to be immediately unreachable/unusable again, so doing that makes no sense. Therefor we decide that a variable declaration is only allowed with a block. A block can have multiple statements, so variables declared in that block can be used by those other statements.
因此,作为语言设计者,我们认为a和b在各自的分支之外是不可见的,以避免这些奇怪的错误。但是由于无块分支只能有一个语句,我们已经声明一个(或b)只能立即再次无法访问/不可用,所以这样做是没有意义的。因此,我们决定只允许使用块进行变量声明。一个块可以有多个语句,因此该块中声明的变量可以被其他语句使用。
The designers of Java probably applied similar reasoning, so they decided to only allow declaration in a block. This is done through the definition of if
(JLS 14.9):
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)
声明(JLS 14.5)
Statement:
StatementWithoutTrailingSubstatement
...
StatementNoShortIf:
StatementWithoutTrailingSubstatement
...
StatementWithoutTrailingSubstatement:
Block
...
Block
(JLS 14.2):
Block(JLS 14.2):
Block:
{ [BlockStatements] }
BlockStatements:
BlockStatement {BlockStatement}
BlockStatement:
LocalVariableDeclarationStatement
ClassDeclaration
Statement
And LocalVariableDeclarationStatement
(JLS 14.4), which repeats that it can only occur within a immediately enclosing block:
和LocalVariableDeclarationStatement(JLS 14.4),它重复它只能发生在一个直接封闭的块中:
Every local variable declaration statement is immediately contained by a block. Local variable declaration statements may be intermixed freely with other kinds of statements in the block.
每个局部变量声明语句都立即被一个块包含。局部变量声明语句可以与块中的其他类型的语句*混合。
#3
13
JLS-14.4. Local Variable Declaration Statements reads (in part),
JLS-14.4。地方变量声明声明(部分),
Every local variable declaration statement is immediately contained by a block.
每个局部变量声明语句都立即被一个块包含。
And
JLS-14.9。如果是Statmenets
Otherwise, execution continues by making a choice based on the resulting value:
否则,通过根据结果值进行选择继续执行:
If the value is true, then the contained Statement is executed; the if-then statement completes normally if and only if execution of the Statement completes normally.
如果值为true,则执行包含的Statement;当且仅当Statement的执行正常完成时,if-then语句才能正常完成。
If the value is false, no further action is taken and the if-then statement completes normally.
如果值为false,则不执行进一步操作,if-then语句正常完成。
However, JLS-14.5. Statements doesn't include variable declaration.
但是,JLS-14.5。声明不包括变量声明。
Defining two different variables within the scope of a single-statement block (containing just the variable definitions) makes them both unreachable. I think you'd have better luck with a ternary expression
在单语句块(仅包含变量定义)的范围内定义两个不同的变量使它们都无法访问。我觉得你的三元表达会更好运
int a = (condition) ? 10 : 20;
or
int a;
if (condition)
a = 10;
else
a = 20;
or
int a;
if (condition) {
a = 10;
} else {
a = 20;
}
Note that the variable a
is then initialized to a value based on the condition
and it is reachable after that statement.
请注意,变量a然后根据条件初始化为一个值,并且在该语句之后可以访问。
#4
6
Every local variable declaration statement is immediately contained by a block. Local variable declaration statements may be intermixed freely with other kinds of statements in the block.
每个局部变量声明语句都立即被一个块包含。局部变量声明语句可以与块中的其他类型的语句*混合。
Read this http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.4
阅读http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.4
#5
0
My best guess is that you cannot declare variables conditionally.
我最好的猜测是你无法有条件地声明变量。
- When you don't have braces, you're trying to declare a variable conditionally in the outer scope, that's not allowed.
- When you add the braces, you're creating the variables in that local scope (which are not allowed to be used outside of those braces)
当你没有大括号时,你试图在外部范围内有条件地声明一个变量,这是不允许的。
添加大括号时,您将在该局部范围内创建变量(不允许在这些大括号外使用)