3

In Java docs I'm reading this: The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs. But finally is useful for more than just exception handling — it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break.

When would you ever exit a try block with a break or continue ? The only scenarios I can think of is you are running a loop inside of a try block and you exit using a break/continue but that should just exit outside of a loop and not the try block itself right?

Phoenix
  • 8,695
  • 16
  • 55
  • 88

5 Answers5

6

When would you ever exit a try block with a break or continue?

When you have a try inside a loop; e.g.

 for (Cat cat : cattery) {
     try {
          cat.removeFromCage();
          cat.healthCheck();
          if (cat.isPedigree()) {
              continue;
          }
          cat.spey();
     } finally {
          cat.putBackInCage();
     }
 }

OK ... so there are more elegant ways of writing that "code" ... but it is just an illustration.

The only scenarios I can think of is you are running a loop inside of a try block and you exit using a break/continue but that should just exit outside of a loop and not the try block itself right?

That is right.


FWIW, any piece of code that involves breaking out of a try block or returning from a catch or finally or any of the other "edge case" things should probably be simplified. The JLS specifies clearly what happens in these scenarios ... but that doesn't mean you should use them in a real program.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
3

Java has labels. And labels usually used with break and continue operator. So, code:

outer: for (int i=0; i < 1; i++){
  for (int j = 0; j < 1; j++) { 
    System.out.println("j:"+j);
    continue outer;
  }
  System.out.println("i:"+i);
}

will print only "j:0"

And because break and continue are 'labeled', you can use "try" statement inside loop block, and inside that block you can try to call "continue" or "break outer_loop". But "finally" statement prevents that exit, as it described in your citation.

Ivan Zelenskyy
  • 659
  • 9
  • 26
  • you mean the presence of `finally` would prevent breaking out of a loop with a inner try/catch? – Aquarius Power Feb 02 '15 at 16:17
  • 1
    @AquariusPower, I mean, that code at link: http://pastebin.com/M76QKXNf will print both prints. So I had show that break/continue statement can be implemented to ANY block, not only to block which is "parent" to "try" block. By other words, author of question didn't knew that break&continue can have a "parameter". – Ivan Zelenskyy Feb 02 '15 at 21:46
  • It is not a good practice to use labels. even though Java allows you to do this. Various looping structures can achieve the same goal and make your code much more readable. – Bogdan Kobylynskyi Mar 11 '21 at 22:36
2

For a completely contrived example:

import java.io.*;

public class Foo {
    public static void main(String[] args) throws IOException {
        for (int i = 0; i < 10; i++) {
            File file = new File("file-" + i);
            FileWriter out = null;
            try {
                out = new FileWriter(file);
                if (file.exists()) return;
                out.write("Number " + i);
                if (i % 2 == 0) continue;
                else if (i % 3 == 0) break;
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                out.close();
            }
        }
    }
}

It's perfectly natural that you might want to return, break, or continue (or throw an exception) inside a try. In this example, if the finally weren't guaranteed to execute, you'd have a resource leak.

And yes, this particular problem is solved by try-with-resource in JDK7.

Ryan Stewart
  • 126,015
  • 21
  • 180
  • 199
1

Yes, break/continue should only affect the loop, not the try/catch/finally block. The doc is just pointing out that it is easy to accidentally miss (not execute) a block of cleanup code when trying to handle exceptions, especially with those sneaky breaks and continues that change the flow!

The finally block should always be executed, unless System.exit() is called or the JVM crashes!

Community
  • 1
  • 1
Nerdwood
  • 3,947
  • 1
  • 21
  • 20
1

Yes possible, Using break statement we can exit try block with help of label and without using loop.

tryLabel:
        try {
            if(true)
                break tryLabel;
            System.out.println("try");
        }catch(Exception e) {
            System.out.println("catch");
            e.printStackTrace();
        }finally{
            System.out.println("finally");
        }
vel
  • 91
  • 1
  • 5