Reputation: 695
Is a label a Java statement or not and if a label is a statement where is it defined as a statement in the Java Language Specification?
My question relates to the following reply of Jan Lahoda in the bug report that I've sent to Oracle. I'm unable to discuss it there because I can't get an account in the OpenJDK Jira.
https://bugs.openjdk.java.net/browse/JDK-8211052
In case of e.g.:
A: B: while (true) continue A;
the statement on which the "continue" is applied is not "while (true) continue A;
", but "B: while (true) continue A;
", and the spec requires the target for continue is a while/do/for statement, which is not fulfilled here. Hence the compile-time error.
I think a label in Java is not a statement and in Jan's example both the A
and the B
labels relate to the same while-loop statement and then no compile time error should be triggered.
Addition:
Isn't a labeled while/do/for statement in Java a while/do/for statement?
Upvotes: 4
Views: 284
Reputation: 57114
Following the JLS a Statement
can be
StatementWithoutTrailingSubstatement
LabeledStatement
IfThenStatement
IfThenElseStatement
WhileStatement
ForStatement
with LabeledStatement
being
Identifier : Statement
and stated
The Identifier is declared to be the label of the immediately contained Statement
so in case of a loop like
public void method() {
loop1: loop2: while (true) {
if (true) {
break loop1;
} else {
continue loop1;
}
}
}
the Statement
of the Label
loop1
is the entire loop2 ...
stuff.
And if we look at the definition of break
it is stated that
the break target need not be a switch, while, do, or for statement.
whereas for the continue
it states
The continue target must be a while, do, or for statement, or a compile-time error occurs.
These definitions are properly in line with the compiler giving a compiler error for the continue loop1
statement and letting break loop1
be valid since loop2: ...
is not a "while, do, or for statement".
Regarding your actual question: Is label a Java statement or not?
The following code is perfectly legal and compiles fine
public void method() {
loop:;
}
This follows the expansion of Statement
-> LabeledStatement
-> Identifier
: Statement
-> loop : Statement
-> loop : StatementWithoutTrailingSubstatement
-> loop : EmptyStatement
->
loop : ;
No, a label is no statement by itself, an identifier (which is then called "label") plus a column plus an EmptyStatement
(;
) however is.
Isn't labeled while/do/for statement in Java a while/do/for statement?
No!
A LabeledStatement
is exactly that: a LabeledStatement
. A labeled while is Statement -> Label -> Identifier : Statement -> Identifier : WhileStatement
which is something fundamentally different than Statement -> WhileStatement
!
Upvotes: 6
Reputation: 178263
The JLS, Section 14.16, talks about the continue
statement:
The continue target must be a
while
,do
, orfor
statement, or a compile-time error occurs.
Simple enough, but let's look at the grammar for a labeled statement (Section 14.7).
LabeledStatement:
Identifier : Statement
It can contain another statements in general, which in turn may be a while
, do
, or for
("wdf") statement, or another labeled statement (Section 14.5) (or other kinds of statements).
But the label by itself is not a statement; it needs the other statement as part of itself.
Next, nested labeled statements are allowed, so in general you can do something like:
A: B: yourStatementHere;
You can nest it further if you want:
A: B: C: D: E: F: G: yourStatementHere;
However, with
A: B: while (true) continue A;
The statement that A:
labels is another labeled statement, not a "wdf" statement, even if the B:
labeled statement itself contains a while
statement.
If you put on your lawyer hat, you can argue that the sentence above about the continue
statement needing to refer to a "wdf" statement says nothing about the "wdf" statement being nested in a labeled statement, so it should be a compiler error.
That seems very picky to me; perhaps the JLS should have had a clause indicating that the "wdf" statement could be itself nested in a labeled statement.
But until that happens, this appears to be a correct, if unintended, consequence of the wording the JLS provides, quoted above.
So why is break
allowed to do this?
A: B: while (true) break A; // no error
There is no corresponding line in Section 14.15 of the JLS, which talks about the break
statement, that enforces that the target of a break
statement must be a "wdf" statement. A break
statement must still be within a "wdf" statement (or a switch
statement), but there is no corresponding requirement that its label refer to a specific kind of statement.
Upvotes: 3