This question already has an answer here:
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?
The Java specification says that an if-then-else
statement is of the following form:
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.
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.
For the full list, you can read the Java specification here: http://docs.oracle.com/javase/specs/
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).
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.
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):
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
And LocalVariableDeclarationStatement
(JLS 14.4), which repeats that it can only occur within a immediately enclosing block:
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.
JLS-14.4. Local Variable Declaration Statements reads (in part),
Every local variable declaration statement is immediately contained by a block.
And
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.
If the value is false, no further action is taken and the if-then statement completes normally.
However, JLS-14.5. Statements doesn't include variable declaration.
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.
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
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)
来源:https://stackoverflow.com/questions/27624402/java-variable-scope-in-if-statement