Why does Java allow for labeled breaks on arbitrar

2019-03-18 14:01发布

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 breaks but not regular breaks? 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.

8条回答
Ridiculous、
2楼-- · 2019-03-18 14:48

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;
        }
    ...
查看更多
冷血范
3楼-- · 2019-03-18 14:49

Why make it so that you can only break out of certain enclosing statements using labeled breaks but not regular breaks

Consider:

while (true) {
    if (condition) {
        break;
    }
}

If the break did as you suggest, this code would perform unexpectedly. Breaks would become a lot more difficult to use.

And why allow for this behavior at all?

I don't use it, but it is a feature and allows for certain unique control-flow constructs. I'd ask you, why not allow it?

查看更多
登录 后发表回答