Reputation: 32083
In short, why is this allowed?
label1: while (condition)
label2: if (condition)
label3: break label3;
I can understand labelling the while
so you can end prematurely, or the if
so you can break one if
and not another, but why break
? When would you need to break
out of the current break
?
After testing, I find that label3: break label3;
runs, but does nothing and continues onto the next line. What's the function of this?
Also note that Java doesn't let you break all statements. For instance, label: Object o = new Object();
gives compiler errors stating that it's not a statement, and that a ;
was expected, even though it does run Object
's constructor method (and, as we see in Why does Java allow for labeled breaks on arbitrary statements?, Java allows you to label method calls; label: new Object();
compiles just fine).
Upvotes: 2
Views: 137
Reputation: 718788
Q1: Why does Java allow this?
As with all language design questions, the only way to get a definitive answer is to ask the designers.
But in this case, this is a useless but harmless edge case on an otherwise useful construct. Since it does no real harm, there is little need to disallow it.
Indeed, there would be a harm in disallowing it. A language restriction that removed this (harmless) edge case would:
make it harder for folks who are building tools that generate Java code,
be extra work for the group of people writing the java specification, and
be extra work for the groups of people who build Java compilers.
Q2: What is the purpose?
It doesn't have a purpose per se. The statement label: break label;
does nothing useful.
But that's fine, there are lots of other ways of writing Java programs that don't do anything useful; e.g. if (true) { }
.
Upvotes: 2
Reputation: 178263
The break
statement is talked about by the JLS, Section 14.15:
A break statement with no label attempts to transfer control to the innermost enclosing switch, while, do, or for statement of the immediately enclosing method or initializer; this statement, which is called the break target, then immediately completes normally.
To be precise, a break statement with no label always completes abruptly, the reason being a break with no label.
If no switch, while, do, or for statement in the immediately enclosing method, constructor, or initializer contains the break statement, a compile-time error occurs.
A break statement with label Identifier attempts to transfer control to the enclosing labeled statement (§14.7) that has the same Identifier as its label; this statement, which is called the break target, then immediately completes normally. In this case, the break target need not be a switch, while, do, or for statement.
To be precise, a break statement with label Identifier always completes abruptly, the reason being a break with label Identifier.
A break statement must refer to a label within the immediately enclosing method, constructor, or initializer. There are no non-local jumps. If no labeled statement with Identifier as its label in the immediately enclosing method, constructor, or initializer contains the break statement, a compile-time error occurs.
There is nothing that states that the label to which break
breaks can't be labelled to something inside the current block. You can always just say break;
to break out of the innermost contained block.
And break
doesn't break out of an if
-- it must be a switch
, while
, do
, or for
, per the JLS above.
The reason that label: Object o = new Object();
doesn't work is because Object o = new Object();
isn't a statement -- it's a declaration. The JLS, Section 14.7 talks about that:
The Identifier is declared to be the label of the immediately contained Statement.
Upvotes: 0