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) {
l开发者_StackOverflowabel1: 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"?
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(); }
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.
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).
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.
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
Refer to Lable in JLS
精彩评论