14

I always thought that the labels must be used only with loops but it seems not. Giving such code:

public class LabelTest {
    public static void main(String[] args) {
        label1: System.out.println("");
        label2: LabelTest t = new LabelTest();  
    }                                               
}

When compiled line labeled "label1" compiles but the code at "label2" gives errors. Why's that? And why would I want to label statements which are not "loops"?

1
  • 1
    What error it gives... Post the complete details.
    – S M Kamran
    Commented Feb 20, 2011 at 15:27

6 Answers 6

18

You get an error because a label cannot be applied to variable declarations, that's just how the language grammar is defined (a label can only precede a Statement, and a LocalVariableDeclarationStatement is not a Statement). The reason is probably that it could cause confusion concerning variable scope. This works:

    label1: System.out.println("");
    label2: { LabelTest t = new LabelTest(); }
2
  • 3
    I think the question was why was the language defined this way? Why not just allow labels preceding for, while and do statements?
    – Avi
    Commented Feb 21, 2011 at 10:31
  • 1
    I included a few examples of where labels could be put that are not before loops statements, but before if statements and blocks in general. These examples are on this page here. Commented Nov 5, 2013 at 21:33
7

To add to Michael Borgwardt's answer, you can do things like this for convenience (I just discovered this the other day while reading through the Java rt.jar source code):

BlockSegment:
if (conditionIsTrue) {
    doSomeProcessing ();
    if (resultOfProcessingIsFalse()) break BlockSegment;
    otherwiseDoSomeMoreProcessing();
    // These lines get skipped if the break statement
    // above gets executed
}
// This is where you resume execution after the break
anotherStatement();

Now, this is logically equivalent to:

if (conditionIsTrue) {
    doSomeProcessing ();
    if (!resultOfProcessingIsFalse()) {
        otherwiseDoSomeMoreProcessing();
        // More code here that gets executed
    }
}
anotherStatement();

But, you get to skip some of the extra braces (and indentations that come with braces). Perhaps it looks cleaner (it does in my opinion), and there are some places where this style of coding may be appropriate and less confusing.

So, you may use labels beyond just loops, and even beyond if statements. For example, this is valid Java syntax (and maybe you could conjure up a reason to do something like this):

statementOne();
statementTwo();
BlockLabel: {
    statementThree();
    boolean result = statementFour();
    if (!result) break BlockLabel;
    statementFive();
    statementSix();
}
statementSeven();

If the break gets executed here, then execution skips to the end of the block denoted by the label, and statementFive() and statementSix() get skipped.

The usefulness of this style (without an if statement) becomes more evident when you have blocks within blocks where you must skip around. In general, you can accomplish everything with smart enough use of loops. However, there are a few cases where labels without loops make for easier reading of code. For example, if you need to sequentially check parameters, you may either do this or throw an exception. It ends up being a matter of cleanliness of code and personal style.

1

It does not compile. Good question! I have just played a little bit with your code snippet. It seems that compiler expects method call or operator after label. It does not allow assignment at this point.

I think that the fact that label is not forbidden before operators other than for, while and do is probably a bug (?!) of java compiler of specification. Anyway it is not so critical. It does not bother me (personally).

1
  • 2
    It's not an assignment, it's an initialization. And it breaks not because of the initialization, but because of a variable declaration. Commented Feb 20, 2011 at 15:48
1

Java syntax is based on C syntax.

In C you can put a label anywhere (not just on loops) and then use goto to jump the execution to that line. Now, goto wasn't implemented in Java, but labels were left so that they can be used in combination with break or continue.

It's not that important since this isn't a standard use of labels anyway. Using labels with continue or break is bad enough (most of the times). Using them freely is also useless.

6
  • Using labels with continue or break is necessary to efficiently implement certain algorithms. However it is completely equivalent to goto.
    – btilly
    Commented Feb 20, 2011 at 15:52
  • 2
    @btilly: Yes, it is necessary sometimes. No, it isn't completely equivalent - it's much safer because the potential lines of code where you can jump are much fewer. For example, you can jump to a loop start, but you can't jump out from a method. Commented Feb 20, 2011 at 15:57
  • @goran-jovic: It is completely equivalent in the sense that any code that can be written with goto can be mechanically rewritten to use continue, break, and labeled loop control with absolutely no loss of efficiency. In practice labeled loop control is not abused as badly, but nothing stops it from happening.
    – btilly
    Commented Feb 20, 2011 at 16:06
  • @btilly: Ok, now I do get your point and you are right. I'd still avoid calling them equivalent since not all gotos can be rewritten using continues and breaks. Commented Feb 20, 2011 at 16:09
  • @btilly: I don't think you need labeled breaks/continues to implement algorithms with inner loops efficient. You can just as well use methods with boolean return values, as long as those function calls are inlined the executed code shouldn't be much different. Though there are cases where that's not clearer, so I don't have problems with labeled breaks - just saying that efficiency shouldn't be much different with modern JITs. Or are there other factors I overlook?
    – Voo
    Commented Feb 20, 2011 at 16:17
0

I am little late to answer this. Anyway,

label2: LabelTest t = new LabelTest(); -> Doesn't work because it is a declarative statement, as most of the above comments state the same. To make it work just do the following:

label2: new LabelTest(); // works fine

-2

Refer to Lable in JLS

1
  • Sarcastic? You could rather refer google.com to figure it out. Commented Apr 15, 2014 at 15:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.