One day I had this dream to start a series of articles going over some of the more obscure and perhaps even harmful features of programming languages. To kick this series off, I wanted to talk about a feature you might not even know exists in Java: labeled statements.
Table of Contents
- What Is a Labeled Statement?
- What Makes Labeled Statements Dark Arts?
- Should You Dabble in the Dark Arts?
What Is a Labeled Statement?
Java lets you label loop scopes using a custom name as follows:
my_loop: for (int i = 0; i < 10; i++) { System.out.println(i); }
Right now, the label serves no purpose. However, if we were to include a break in the code, we could reference the label directly:
my_loop: for (int i = 0; i < 10; i++) { System.out.println(i); if (i == 7) { break my_loop; } }
Again, whether we label this break or not has no effect on the behavior of the code. What makes a labeled break different from an unlabeled break is that we can now control where the break goes.
Normally, a break exits the innermost loop. For example, if we have the following nested loop, the break statement would only exit the innermost loop:
for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { if (i == 5) { break; } } }
However, if we introduce our label, we can break both loops simultaneously:
my_loop: for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { if (i == 5) { break my_loop; } } }
The same technique can be used on while loops and do-while loops as well as switch statements. The same trick can also be used with the
continue
keyword, meaning you can now skip iterations of outer loops.
What Makes Labeled Statements Dark Arts?
If you’ve had the pleasure of writing low-level code before, such as assembly, then you’re certainly familiar with the “goto” statement—or at least the concept of a “jump.” See, before programming became more structured, code was written sequentially. Therefore, if we wanted to repeat a section of code or branch to another section of code, we would use a jump to get to the correct line.
To illustrate what I mean, here’s some pseudocode:
parry attack block goto 1
The simple code above demonstrates an infinite loop in pseudo-assembly. The three actions are performed and then we’re told to repeat them by returning back to the first line.
We can replicate the behavior of all the structures we’re used to with a “goto.” Typically, that is done using a pair of lines. For example, if we wanted to fix the infinite loop problem, we would just need to include two additional lines up front:
if not enemy goto 7 parry attack block goto 1
Now, if there is not an enemy, we jump all the way to line 7 to terminate the loop. Otherwise, we perform our three actions and go back to the first line.
As software development became more structured, the “goto” statement rapidly became a dark art in its own right, even to the point of spawning an xkcd comic. In fact, the “goto” statement is so hated that it spawned a lot of interesting beliefs around contemporary code, such as the idea that methods should only have one return statement.
Of course, nothing in structured programming really compares to the “goto” statement beyond itself and what I’ve introduced you to today: labeled statements.
Should You Dabble in the Dark Arts?
Personally, I would never use labeled statements in my code. There may be some niche situations where they make sense. However, if the goal of programming is to produce code that doesn’t just work but is also readable, then labeled statements seem bad. After all, how many of you have even seen them used, let alone knew they existed?
To me, I find it strange that we’re so afraid of telling people to not use certain coding features just because they might have some utility in some rare case. The reality is that coding is a skill and that repetition leads to mastery. Unless you’re using these labeled statements regularly, I don’t trust you to use them appropriately.
Not to mention that while I was reading about labels, I saw a truly horrific code sample:
class MyFirstJavaProg { public static void main(String args[]) { http://www.javacoffeebreak.com/java101/java101.html System.out.println("Hello World!"); } }
The credit on that one goes to Peter Lawrey back in 2009. Talk about dark arts. This makes me want to get back into obfuscation techniques!
Anyway, I thought this was a quick fun article today. As I find more disturbing language features, I’ll surely share them in this series.
In the meantime, thanks for checking this out! I hope you enjoyed it. If you liked this, there isn’t too much like it, but I do dabble in obfuscation, which is close:
- Obfuscation Techniques: Magic Numbers
- Obfuscation Techniques: Visually Similar Characters
- Obfuscation Techniques: The Yoda Conditional
Likewise, you can start supporting the site, which goes a long way to keeping this content coming. Otherwise, thanks for sticking around!
Recent Code Posts
Contrary to my piece from a couple years ago, I'm actually coming out in favor of incorporating loop invariants in computer science education—albeit with more of a focus on reasoning than formal...
Recently, I was thinking about how there are so many ways to approach software design. While some of these approaches have fancy names, I'm not sure if anyone has really thought about them...