Dark Arts: Labeled Statements in Java

A photo of lightning with the title of the article overlayed.

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?

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 statementsOpens in a new tab.. 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 comicOpens in a new tab.. 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 2009Opens in a new tab.. 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:

Likewise, you can start supporting the site, which goes a long way to keeping this content coming. Otherwise, thanks for sticking around!

Jeremy Grifski

Jeremy grew up in a small town where he enjoyed playing soccer and video games, practicing taekwondo, and trading Pokémon cards. Once out of the nest, he pursued a Bachelors in Computer Engineering with a minor in Game Design. After college, he spent about two years writing software for a major engineering company. Then, he earned a master's in Computer Science and Engineering. Most recently, he earned a PhD in Engineering Education and now works as a Lecturer. In his spare time, Jeremy enjoys spending time with his wife and kid, playing Overwatch 2, Lethal Company, and Baldur's Gate 3, reading manga, watching Penguins hockey, and traveling the world.

Recent Code Posts