I just learned today that the following Java code is perfectly legal:
myBlock: {
/* ... code ... */
if (doneExecutingThisBlock())
break myBlock;
/* ... more code ... */
}
Note that myBlock
isn't a loop - it's just a block of code I've delimited with curly braces.
This seems like a rather strange feature to have. It means that you can use a named break
to break out of an if
statement or anonymous block, though you can't normally use a break
statement in these contexts.
My question is this: is there a good reason for this design decision? That is, why make it so that you can only break out of certain enclosing statements using labeled break
s but not regular break
s? And why allow for this behavior at all? Given how (comparatively) well-designed Java is as a language I would assume there's a reason for this, but I honestly can't think of one.
It is plausible that this was done for simplicity. If originally the labeled break can only break loop statements, then it should be immediately clear to language designer that the restriction isn't necessary, the semantics work the same for all statements. For the economics of the language spec, and simpler implementation of compilers, or just out of the habit towards generality, labeled break is defined for any statement, not just loop statements.
Now we can look back and judge this choice. Does it benefit programmers, by giving them extra expression power? Seems very little, the feature is rarely used. Does it cost programmers in learning and understanding? Seems so, as evidenced by this discussion.
If you could go back time and change it, would you? I can't say I would. We have a fetish for generality.
If in a parallel universe it was limited to loop statements only, there is still a chance, probably much smaller, that someone posts the question on stackoverflow: why couldn't it work on arbitrary statements?
Think of it as a
return
statement that returns from the block instead of from the entire function. The same reasoning you apply to object tobreak
being scattered anywhere can also be applied toreturn
being allowed anywhere except at the end of a function.It seems to be useful to exit nested loops. See http://download.oracle.com/javase/tutorial/java/nutsandbolts/branch.html
It's semantically the same as is there a equivalent of Java's labelled break in C# or a workaround
The issue with goto is that it can jump forward, past code. A labeled break cannot do that (it can only go backwards). IIRC C++ has to deal with goto jumping past code (it is been over 17 years since I cared about that though so I am not sure I am remembering that right).
Java was designed to be used by C/C++ programmers, so many things were done to make it familiar to those developers. It is possible to do a reasonable translation from C/C++ to Java (though some things are not trivial).
It is reasonable to think that they put that into the language to give C/C++ developers a safe goto (where you can only go backwards in the code) to make it more comfortable to some programmers converting over.
I have never seen that in use, and I have rarely seen a labeled break at all in 16+ years of Java programming.
You cannot break forward:
Adding to Stephen C's answer,
if (something)
you cannot break out of a nested loop. These situations do happen in numerical algorithms. One simple example here - you cannot break out of the i-loop without the named for. Hope this helps.Yes. Because it works.
In the labelled break case, the fact that you don't need to be inside a loop or switch lets you to express things that are harder to express in other ways. (Admittedly, people rarely do use labelled break this way ... but that's not a fault of the language design.)
In the unlabelled break case, the behaviour is to break out of the innermost enclosing loop or switch. If it was to break out of the innermost enclosing statement, then a lot of things would be much harder to express, and many would probably require a labelled block. For example:
If
break
broke out of the innermost enclosing statement, then it wouldn't break out of the loop.