Please explain the usage of Labeled Statements
JLS 14.7 Labeled statements
(edited for clarity)
Statements may have label prefixes (Identifier : Statement). The Identifier is declared to be the label of the immediately contained Statement.
Unlike C and C++, the Java programming language has no
goto
statement; identifier statement labels are used withbreak
(§14.15) orcontinue
(§14.16) statements appearing anywhere within the labeled statement.
So the JLS is clear that labels are used with break
or continue
, and no other grammatical element of the Java programming language uses it.
Strictly speaking, break
and continue
, labeled or not, are NEVER necessary. They can always be written out of the code. Used idiomatically, however, they can lead to more readable code.
Here's an illustrative example: given an int[]
, we want to :
- print
"One (1)"
on1
- print
"Two (2)"
on2
- print
"Zero "
on0
immediately stop processing on any other number
int[] arr = { 1, 2, 0, 1, -1, 0, 2 }; loop: for (int num : arr) { switch (num) { case 1: System.out.print("One "); break; case 2: System.out.print("Two "); break; case 0: System.out.print("Zero "); continue loop; default: break loop; } System.out.print("(" + num + ") "); } // prints "One (1) Two (2) Zero One (1) "
Here we see that:
- The different numbers are processed in a
switch
- Unlabeled
break
in theswitch
is used to avoid "fall-through" between cases - Labeled
continue loop;
is used to skip post-processing oncase 0:
(the label is not necessary here) - Labeled
break loop;
is used to terminate the loop ondefault:
(the label is necessary here; otherwise it's aswitch break
)
So labeled break
/continue
can also be used outside of nested loops; it can be used when a switch
is nested inside a loop. More generally, it's used when there are potentially multiple break
/continue
target, and you want to choose one that is not immediately enclosing the break
/continue
statement.
Here's another example:
morningRoutine: {
phase1: eatBreakfast();
if (grumpy) break morningRoutine;
phase2: kissWife();
phase3: hugChildren();
}
http://stackoverflow.com is the best website ever!
Here's another case of a labeled break
being used not within an iterative statement, but rather within a simple block statement. One may argue that the labels lead to better readability; this point is subjective.
And no, the last line DOES NOT give compile time error. It's actually inspired by Java Puzzlers Puzzle 22: Dupe of URL. Unfortunately, the puzzle does not go into "proper" use of labeled statements in more depth.
Yes, break
and continue
are the only two uses for labeled statements in Java. (Java has no goto
statement.)
You can use a label to break out of nested loops.
outer:
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
System.out.println("Hello");
continue outer;
} // end of inner loop
System.out.println("outer"); // Never prints
}
System.out.println("Good-Bye");
When you continue
back to the outer
label, you're skipping the remainder of both the inner and the outer loop, including the print statement.
search:
for (i = 0; i < arrayOfInts.length; i++) {
for (j = 0; j < arrayOfInts[i].length; j++) {
if (arrayOfInts[i][j] == searchfor) {
foundIt = true;
break search;
}
}
}