I just learned today that the following Java code is perfectly legal:
myBlock: {
/* ... code ... */
if (doneExecutingThisBlock())
break myBlock;
The break statement terminates the labeled statement; it does not transfer the flow of control to the label. Control flow is transferred to the statement immediately following the labeled (terminated) statement.
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
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 to break
being scattered anywhere can also be applied to return
being allowed anywhere except at the end of a function.
It's the "structured" equivalent to a goto, useful in certain circumstances.
I quite often use such a label create named sub-blocks in a method to tightly limit scope of variables or to simply label a block of code which is not appropriate to break out into a separate function. That is, I use it to label a block so that the code structure around braces is preserved. Here's an example in C for a JNI call, and I do the same in Java:
JNIEXPORT void JNICALL Java_xxx_SystemCall_jniChangePassword(JNIEnv *jep, jobject thsObj,
jlong handle, jbyteArray rndkey, jbyteArray usrprf, jbyteArray curpwd, jbyteArray newpwd, jint pwdccs, jint tmosec) {
Message rqs,rpy;
thsObj=thsObj;
SetupRequest: {
memset(&rqs,0,sizeof(rqs));
setOpcode(&rqs,"CHGPWD");
if(!setField(mFldAndLen(rqs.rnd ),null ,jep,rndkey,"Random Key")) {
return;
}
if(!setField(mFldAndLen(rqs.dta.chgpwd.user ),&rqs.dta.chgpwd.userLen ,jep,usrprf,"User Profile")) {
return;
}
if(!setField(mFldAndLen(rqs.dta.chgpwd.curPass),&rqs.dta.chgpwd.curPassLen,jep,curpwd,"Cur Password")) {
return;
}
if(!setField(mFldAndLen(rqs.dta.chgpwd.newPass),&rqs.dta.chgpwd.newPassLen,jep,newpwd,"New Password")) {
return;
}
rqs.dta.chgpwd.ccsid=pwdccs;
}
...