Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Before I start this question I know the java 'goto' is a big no go.

So I've been writing a program and I have some indented Loops and statements and I need to BREAK multiple on command. Rather than having a load of boolean variables and if(!<booleanName>) BREAK; statements throughout these loops and statements what is everyone's opinions on using labels to break them using the BREAK <label> statement?

e.g.

 for(...) {

      indented_example_loops:     // Label name
           for(...) {
                for(...) {
                     if(match) break indented_example_loops;
                     // ^ Break statement to break the 2 for loops at once
                }
           }

 }

Perfectly okay? Okay to do occasionally? Completely avoid? or should i go to a corner and call the Devil to take my soul?

share|improve this question
3  
I for one think your problem is the deep nesting, not a use or abuse of labels and goto –  Vain Fellowman Feb 5 '13 at 9:26
    
The nesting is necessary as its lists nested inside lists i.e. Group > Member > Emails/Addresses/Phone-Numbers –  Skepi Feb 5 '13 at 9:37
7  
Put the nested code in a separate method and use return instead of break. Structured programming was invented more than 40 years ago (en.wikipedia.org/wiki/Structured_program_theorem) for good reasons. –  Giorgio Feb 5 '13 at 10:17
2  
@Giorgio, you should make that an answer. –  Karl Bielefeldt Feb 5 '13 at 15:20
2  
break, continue, throw, switch, and return are all forms of the much maligned goto. Some of this is warranted, some is not. Labels can make these structures easier to read or harder. Treat them all with respect. –  MichaelT Feb 5 '13 at 23:27

3 Answers 3

up vote 17 down vote accepted

It's all about readability and ease of understanding.

The easiest to understand loops are those with simple end conditions and no breaks at all. So if you can write your loops like that, do it.

while (someCondition) {
  // do stuff
}

Next comes the loop with a simple end condition and a single break:

while (someCondition) {
  // do stuff
  if (otherCondition) {
    break;
  }
  // maybe some more stuff
}

Everything that's more complex than this is a potential problem. A break with a label is always tricky, because you'll have to hunt for the label to find out which statement/block the break escapes from (i.e. the break will continue after the labeled block/statement).

The worst kind (the one you almost always want to avoid) is a nested loop where you break somewhere in the middle.

while (someCondition) {
  myLabel:
  for (Foo foo : getAllFoos()) {
    for (Bar bar : foo.getBars()) {
      // do stuff
      if (someCondition(bar)) {
        break myLabel; // BAD!
      }
      // some more stuff
    }
  }
}

The problem here is that the actual flow of processing becomes really hard to follow. If you start having code like this, then you should definitely refactor it.

A common refactoring is to extract one (or more) nested loops into a method and turning the break into a return. This has the added benefit of giving a name to that piece of the code. If the name is chosen well, then that will help greatly in understanding the code.

share|improve this answer
    
Thanks, ill take this into account. I guess using methods and return statements would give me the same result and be a lot easier to read –  Skepi Feb 5 '13 at 9:38
    
+1 even if I dislike break in any case (except switch). –  Uwe Plonus Feb 5 '13 at 9:45
1  
@UwePlonus: I think on the "low end" (simple breaks), it's mostly a matter of taste, and I won't argue against avoiding it altogether. The most important part (in my opinion) is to avoid the really hard to read constructs with nested loops and multiple break labels. Those are mind-benders and not usually worth the trouble. –  Joachim Sauer Feb 5 '13 at 9:54

You are opening yourself up to spaghetti code

While the language allows you to do this, it is not good practice. There are many alternative looping structures that will achieve the same objective and make your code much more readable.

Essentially, labels and gotos are a holdover from assembly language code (which is all about labels and gotos). It really has no place in higher level languages.

share|improve this answer

Separate the iteration and the processing by encapsulating the iteration.

Iterating over multi-level structures with nested loops leads to applications where most of the code is looping noise. To process all the Level2Things in a Level0Thing, replace your nested loops with this:

for (Level2Thing t2: topThing.level2Things()) {
   // do something
}

where level2Things() returns an Iterable<Level2Thing>.

You can find some sample code for encapsulating nested iterations here.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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