Exiting a try block using break/continue in Java - java

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?

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.

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.

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.

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!

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");
}

Related

Does surrounding try/catch break the forloop?

In the code below I was wondering if an exception was thrown in the for loop and the error message was added to the JSON object in the catch block, will the program return to the next iteration of the for loop after the exception was thrown? Or will it break the for loop and return the object?
JSONOBject obj = new JSONObject();
try
{
for(i=0; i<10; i++)
{
//do things in here that may throw an exception
obj.put("message","did not throw exception");
}
{
catch(Exception e)
{
obj.put("message",e.getMessage());
}
return obj;
An exception will terminate the method, because after the catch block the next statement is return.
If you want to continue the loop, put the entire try/catch inside the loop, as in:
for (.... whatever ...)
{
try
{
something
}
catch(Exception e)
{
obj.put("message",e.getMessage());
}
}
In this case the loop will execute all specified iterations, and each exception caught will add a new message to obj.
No - the loop will be exited from the point when the exception is thrown - after catch block is done with.
In a try block as soon as an error is thrown execution in that block stops and control jumps over to the catch block. Therefore in your case the rest of the for loop is not executed.
You can move the try catch into the for loop if you wish to continue through the for loop.

Java - If I return in a catch block, will the finally block be executed? [duplicate]

This question already has answers here:
Does a finally block always get executed in Java?
(51 answers)
Closed 9 years ago.
This is what I'm trying to do:
try {
//code
} catch (Exception e) {
return false;
} finally {
//close resources
}
Will this work? Is it bad practice? Would it be better doing this:
boolean inserted = true;
try {
//code
} catch (Exception e) {
inserted = false;
} finally {
//close resources
}
return inserted;
Yes, it will. The only things that can prevent a finally block to execute (AFAIR) are System.exit(), and an infinite loop (and a JVM crash, of course).
The finally block is executed always, unconditionally, as the last thing the try-catch-finally block does. Even if you execute Thread#stop against it, the finally block will still execute, just as if a regular exception ocurred.
Not just that, if you return from finally, that return value will trample over the return from either try or catch.
BTW Your first example is not just fine, but preferred. In the second example the reader must chase around the assignments to the variable, which is a tedious job and lets bugs slip through very easily.
Both are approximately the same. However, be careful with the following case:
int i = 0;
try
{
//code
}
catch(Exception e)
{
return i;
}
finally
{
i = 1;
}
0 is what will be returned.
I just wanted to add that it's described in the specs:
If the catch block completes abruptly for reason R, then the finally block is executed.
where of course
It can be seen, then, that a return statement always completes abruptly.

How can I break from a try/catch block without throwing an exception in Java

I need a way to break from the middle of try/catch block without throwing an exception.
Something that is similar to the break and continue in for loops.
Is this possible?
I have been getting weird throughts about throwing a custom exception (naming it "BreakContinueException") that simple does nothing in its catch handler. I'm sure this is very twisted.
So, any straight forward solution I'm not aware of?
The proper way to do it is probably to break down the method by putting the try-catch block in a separate method, and use a return statement:
public void someMethod() {
try {
...
if (condition)
return;
...
} catch (SomeException e) {
...
}
}
If the code involves lots of local variables, you may also consider using a break from a labeled block, as suggested by Stephen C:
label: try {
...
if (condition)
break label;
...
} catch (SomeException e) {
...
}
You can always do it with a break from a loop construct or a labeled break as specified in aioobies answer.
public static void main(String[] args) {
do {
try {
// code..
if (condition)
break;
// more code...
} catch (Exception e) {
}
} while (false);
}
Various ways:
return
break or continue when in a loop
break to label when in a labeled statement (see #aioobe's example)
break when in a switch statement.
...
System.exit() ... though that's probably not what you mean.
In my opinion, "break to label" is the most natural (least contorted) way to do this if you just want to get out of a try/catch. But it could be confusing to novice Java programmers who have never encountered that Java construct.
But while labels are obscure, in my opinion wrapping the code in a do ... while (false) so that you can use a break is a worse idea. This will confuse non-novices as well as novices. It is better for novices (and non-novices!) to learn about labeled statements.
By the way, return works in the case where you need to break out of a finally. But you should avoid doing a return in a finally block because the semantics are a bit confusing, and liable to give the reader a headache.
There are several ways to do it:
Move the code into a new method and return from it
Wrap the try/catch in a do{}while(false); loop.
This is the code I usually do:
try
{
...........
throw null;//this line just works like a 'break'
...........
}
catch (NullReferenceException)
{
}
catch (System.Exception ex)
{
.........
}
In this sample in catch block i change the value of counter and it will break while block:
class TestBreak {
public static void main(String[] a) {
int counter = 0;
while(counter<5) {
try {
counter++;
int x = counter/0;
}
catch(Exception e) {
counter = 1000;
}
}
}
}k

Exception with try-catch and loop in Java

In Java, what is the difference (in term of performance) between:
for (int i = 0; i < count; i++) {
try {
// code that throws Exception
} catch (Exception e) {
e.printStackTrace();
}
}
and
try {
for (int i = 0; i < count; i++) {
// code that throws Exception
}
} catch (Exception e) {
e.printStackTrace();
}
In your first version the loop continues if it hits an exception, in the second version the loop continues after the catch block. That is the most important difference of those code snippets.
You can use both, but it all depends on what you want it to do. If you want to continue the execution after the loop finishes once then you do it the first way. If you want to catch an exception then stop executing the loop then you do the second. Performance wise it all depends on what you want to do with it.
The main difference is that in the first snippet of code, even if there is an exception thrown from the try block and it is caught execution of the for loop continues. In the second snippet if an exception is thrown then the for loop is exited. This is because the whole loop is within the try block.
No I'm quite sure there's absolutely no difference from a point of performance here (ignoring the obvious fact about the loop). In both cases you create exactly one entry in the exception table - only the PC values (ie in which range the exception is valid) will be a bit different.
ie if you assume the following is the exception table the only thing that'll change are the x, y and z values..
Exception table:
from to target type
x y z <Class java.lang.Exception>
Since you asked about performance in the two versions of code, I am reminded of "Practical Java" (Addison-Wesley 2000) which recommends in Praxis 23: Place try/catch blocks outside of loops. The reason involves running the code on a JVM with the JIT compiler turned off. In that case, the lack of run-time JIT optimizations results in extra branches in the opcode, leading to reduced performance. You can read JIT docs of 2014 here: http://www.oracle.com/technetwork/articles/java/architect-evans-pt1-2266278.html
Besides the difference in your logic with the continuing for. It's no noticeable difference between
try {
lots of stuff which might not throw any exception
something that throws exception
} catch (Exception e) {
}
and
lots of stuff which might not throw any exception
try {
something that throws exception
} catch (Exception e) {
}

Does a finally block always get executed in Java?

Considering this code, can I be absolutely sure that the finally block always executes, no matter what something() is?
try {
something();
return success;
}
catch (Exception e) {
return failure;
}
finally {
System.out.println("I don't know if this will get printed out");
}
Yes, finally will be called after the execution of the try or catch code blocks.
The only times finally won't be called are:
If you invoke System.exit()
If you invoke Runtime.getRuntime().halt(exitStatus)
If the JVM crashes first
If the JVM reaches an infinite loop (or some other non-interruptable, non-terminating statement) in the try or catch block
If the OS forcibly terminates the JVM process; e.g., kill -9 <pid> on UNIX
If the host system dies; e.g., power failure, hardware error, OS panic, et cetera
If the finally block is going to be executed by a daemon thread and all other non-daemon threads exit before finally is called
Example code:
public static void main(String[] args) {
System.out.println(Test.test());
}
public static int test() {
try {
return 0;
}
finally {
System.out.println("something is printed");
}
}
Output:
something is printed.
0
Also, although it's bad practice, if there is a return statement within the finally block, it will trump any other return from the regular block. That is, the following block would return false:
try { return true; } finally { return false; }
Same thing with throwing exceptions from the finally block.
Here's the official words from the Java Language Specification.
14.20.2. Execution of try-finally and try-catch-finally
A try statement with a finally block is executed by first executing the try block. Then there is a choice:
If execution of the try block completes normally, [...]
If execution of the try block completes abruptly because of a throw of a value V, [...]
If execution of the try block completes abruptly for any other reason R, then the finally block is executed. Then there is a choice:
If the finally block completes normally, then the try statement completes abruptly for reason R.
If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).
The specification for return actually makes this explicit:
JLS 14.17 The return Statement
ReturnStatement:
return Expression(opt) ;
A return statement with no Expression attempts to transfer control to the invoker of the method or constructor that contains it.
A return statement with an Expression attempts to transfer control to the invoker of the method that contains it; the value of the Expression becomes the value of the method invocation.
The preceding descriptions say "attempts to transfer control" rather than just "transfers control" because if there are any try statements within the method or constructor whose try blocks contain the return statement, then any finally clauses of those try statements will be executed, in order, innermost to outermost, before control is transferred to the invoker of the method or constructor. Abrupt completion of a finally clause can disrupt the transfer of control initiated by a return statement.
In addition to the other responses, it is important to point out that 'finally' has the right to override any exception/returned value by the try..catch block. For example, the following code returns 12:
public static int getMonthsInYear() {
try {
return 10;
}
finally {
return 12;
}
}
Similarly, the following method does not throw an exception:
public static int getMonthsInYear() {
try {
throw new RuntimeException();
}
finally {
return 12;
}
}
While the following method does throw it:
public static int getMonthsInYear() {
try {
return 12;
}
finally {
throw new RuntimeException();
}
}
Here's an elaboration of Kevin's answer. It's important to know that the expression to be returned is evaluated before finally, even if it is returned after.
public static void main(String[] args) {
System.out.println(Test.test());
}
public static int printX() {
System.out.println("X");
return 0;
}
public static int test() {
try {
return printX();
}
finally {
System.out.println("finally trumps return... sort of");
return 42;
}
}
Output:
X
finally trumps return... sort of
42
I tried the above example with slight modification-
public static void main(final String[] args) {
System.out.println(test());
}
public static int test() {
int i = 0;
try {
i = 2;
return i;
} finally {
i = 12;
System.out.println("finally trumps return.");
}
}
The above code outputs:
finally trumps return.
2
This is because when return i; is executed i has a value 2. After this the finally block is executed where 12 is assigned to i and then System.out out is executed.
After executing the finally block the try block returns 2, rather than returning 12, because this return statement is not executed again.
If you will debug this code in Eclipse then you'll get a feeling that after executing System.out of finally block the return statement of try block is executed again. But this is not the case. It simply returns the value 2.
That is the whole idea of a finally block. It lets you make sure you do cleanups that might otherwise be skipped because you return, among other things, of course.
Finally gets called regardless of what happens in the try block (unless you call System.exit(int) or the Java Virtual Machine kicks out for some other reason).
A logical way to think about this is:
Code placed in a finally block must be executed whatever occurs within the try block
So if code in the try block tries to return a value or throw an exception the item is placed 'on the shelf' till the finally block can execute
Because code in the finally block has (by definition) a high priority it can return or throw whatever it likes. In which case anything left 'on the shelf' is discarded.
The only exception to this is if the VM shuts down completely during the try block e.g. by 'System.exit'
finally is always executed unless there is abnormal program termination (like calling System.exit(0)..). so, your sysout will get printed
No, not always one exception case is//
System.exit(0);
before the finally block prevents finally to be executed.
class A {
public static void main(String args[]){
DataInputStream cin = new DataInputStream(System.in);
try{
int i=Integer.parseInt(cin.readLine());
}catch(ArithmeticException e){
}catch(Exception e){
System.exit(0);//Program terminates before executing finally block
}finally{
System.out.println("Won't be executed");
System.out.println("No error");
}
}
}
Also a return in finally will throw away any exception. http://jamesjava.blogspot.com/2006/03/dont-return-in-finally-clause.html
The finally block is always executed unless there is abnormal program termination, either resulting from a JVM crash or from a call to System.exit(0).
On top of that, any value returned from within the finally block will override the value returned prior to execution of the finally block, so be careful of checking all exit points when using try finally.
Finally is always run that's the whole point, just because it appears in the code after the return doesn't mean that that's how it's implemented. The Java runtime has the responsibility to run this code when exiting the try block.
For example if you have the following:
int foo() {
try {
return 42;
}
finally {
System.out.println("done");
}
}
The runtime will generate something like this:
int foo() {
int ret = 42;
System.out.println("done");
return 42;
}
If an uncaught exception is thrown the finally block will run and the exception will continue propagating.
NOT ALWAYS
The Java Language specification describes how try-catch-finally and try-catch blocks work at 14.20.2
In no place it specifies that the finally block is always executed.
But for all cases in which the try-catch-finally and try-finally blocks complete it does specify that before completion finally must be executed.
try {
CODE inside the try block
}
finally {
FIN code inside finally block
}
NEXT code executed after the try-finally block (may be in a different method).
The JLS does not guarantee that FIN is executed after CODE.
The JLS guarantees that if CODE and NEXT are executed then FIN will always be executed after CODE and before NEXT.
Why doesn't the JLS guarantee that the finally block is always executed after the try block? Because it is impossible. It is unlikely but possible that the JVM will be aborted (kill, crash, power off) just after completing the try block but before execution of the finally block. There is nothing the JLS can do to avoid this.
Thus, any software which for their proper behaviour depends on finally blocks always being executed after their try blocks complete are bugged.
return instructions in the try block are irrelevant to this issue. If execution reaches code after the try-catch-finally it is guaranteed that the finally block will have been executed before, with or without return instructions inside the try block.
Yes it will get called. That's the whole point of having a finally keyword. If jumping out of the try/catch block could just skip the finally block it was the same as putting the System.out.println outside the try/catch.
Because a finally block will always be called unless you call System.exit() (or the thread crashes).
Concisely, in the official Java Documentation (Click here), it is written that -
If the JVM exits while the try or catch code is being executed, then
the finally block may not execute. Likewise, if the thread executing
the try or catch code is interrupted or killed, the finally block may
not execute even though the application as a whole continues.
This is because you assigned the value of i as 12, but did not return the value of i to the function. The correct code is as follows:
public static int test() {
int i = 0;
try {
return i;
} finally {
i = 12;
System.out.println("finally trumps return.");
return i;
}
}
Answer is simple YES.
INPUT:
try{
int divideByZeroException = 5 / 0;
} catch (Exception e){
System.out.println("catch");
return; // also tried with break; in switch-case, got same output
} finally {
System.out.println("finally");
}
OUTPUT:
catch
finally
finally block is always executed and before returning x's (calculated) value.
System.out.println("x value from foo() = " + foo());
...
int foo() {
int x = 2;
try {
return x++;
} finally {
System.out.println("x value in finally = " + x);
}
}
Output:
x value in finally = 3
x value from foo() = 2
Yes, it will. No matter what happens in your try or catch block unless otherwise System.exit() called or JVM crashed. if there is any return statement in the block(s),finally will be executed prior to that return statement.
Adding to #vibhash's answer as no other answer explains what happens in the case of a mutable object like the one below.
public static void main(String[] args) {
System.out.println(test().toString());
}
public static StringBuffer test() {
StringBuffer s = new StringBuffer();
try {
s.append("sb");
return s;
} finally {
s.append("updated ");
}
}
Will output
sbupdated
Yes It will.
Only case it will not is JVM exits or crashes
Yes, finally block is always execute. Most of developer use this block the closing the database connection, resultset object, statement object and also uses into the java hibernate to rollback the transaction.
finally will execute and that is for sure.
finally will not execute in below cases:
case 1 :
When you are executing System.exit().
case 2 :
When your JVM / Thread crashes.
case 3 :
When your execution is stopped in between manually.
I tried this,
It is single threaded.
public static void main(String args[]) throws Exception {
Object obj = new Object();
try {
synchronized (obj) {
obj.wait();
System.out.println("after wait()");
}
} catch (Exception ignored) {
} finally {
System.out.println("finally");
}
}
The main Thread will be on wait state forever, hence finally will never be called,
so console output will not print String: after wait() or finally
Agreed with #Stephen C, the above example is one of the 3rd case mention here:
Adding some more such infinite loop possibilities in following code:
// import java.util.concurrent.Semaphore;
public static void main(String[] args) {
try {
// Thread.sleep(Long.MAX_VALUE);
// Thread.currentThread().join();
// new Semaphore(0).acquire();
// while (true){}
System.out.println("after sleep join semaphore exit infinite while loop");
} catch (Exception ignored) {
} finally {
System.out.println("finally");
}
}
Case 2: If the JVM crashes first
import sun.misc.Unsafe;
import java.lang.reflect.Field;
public static void main(String args[]) {
try {
unsafeMethod();
//Runtime.getRuntime().halt(123);
System.out.println("After Jvm Crash!");
} catch (Exception e) {
} finally {
System.out.println("finally");
}
}
private static void unsafeMethod() throws NoSuchFieldException, IllegalAccessException {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
Unsafe unsafe = (Unsafe) f.get(null);
unsafe.putAddress(0, 0);
}
Ref: How do you crash a JVM?
Case 6: If finally block is going to be executed by daemon Thread and all other non-daemon Threads exit before finally is called.
public static void main(String args[]) {
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
printThreads("Daemon Thread printing");
// just to ensure this thread will live longer than main thread
Thread.sleep(10000);
} catch (Exception e) {
} finally {
System.out.println("finally");
}
}
};
Thread daemonThread = new Thread(runnable);
daemonThread.setDaemon(Boolean.TRUE);
daemonThread.setName("My Daemon Thread");
daemonThread.start();
printThreads("main Thread Printing");
}
private static synchronized void printThreads(String str) {
System.out.println(str);
int threadCount = 0;
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for (Thread t : threadSet) {
if (t.getThreadGroup() == Thread.currentThread().getThreadGroup()) {
System.out.println("Thread :" + t + ":" + "state:" + t.getState());
++threadCount;
}
}
System.out.println("Thread count started by Main thread:" + threadCount);
System.out.println("-------------------------------------------------");
}
output: This does not print "finally" which implies "Finally block" in "daemon thread" did not execute
main Thread Printing
Thread :Thread[My Daemon Thread,5,main]:state:BLOCKED
Thread :Thread[main,5,main]:state:RUNNABLE
Thread :Thread[Monitor Ctrl-Break,5,main]:state:RUNNABLE
Thread count started by Main thread:3
-------------------------------------------------
Daemon Thread printing
Thread :Thread[My Daemon Thread,5,main]:state:RUNNABLE
Thread :Thread[Monitor Ctrl-Break,5,main]:state:RUNNABLE
Thread count started by Main thread:2
-------------------------------------------------
Process finished with exit code 0
Consider the following program:
public class SomeTest {
private static StringBuilder sb = new StringBuilder();
public static void main(String args[]) {
System.out.println(someString());
System.out.println("---AGAIN---");
System.out.println(someString());
System.out.println("---PRINT THE RESULT---");
System.out.println(sb.toString());
}
private static String someString() {
try {
sb.append("-abc-");
return sb.toString();
} finally {
sb.append("xyz");
}
}
}
As of Java 1.8.162, the above code block gives the following output:
-abc-
---AGAIN---
-abc-xyz-abc-
---PRINT THE RESULT---
-abc-xyz-abc-xyz
this means that using finally to free up objects is a good practice like the following code:
private static String someString() {
StringBuilder sb = new StringBuilder();
try {
sb.append("abc");
return sb.toString();
} finally {
sb = null; // Just an example, but you can close streams or DB connections this way.
}
}
That's actually true in any language...finally will always execute before a return statement, no matter where that return is in the method body. If that wasn't the case, the finally block wouldn't have much meaning.
In addition to the point about return in finally replacing a return in the try block, the same is true of an exception. A finally block that throws an exception will replace a return or exception thrown from within the try block.

Categories