Related
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.
This was an interview question:
public class Demo {
public static void main(String[] args) {
System.out.println(foo());
}
static String foo() {
try {
return "try ...";
} catch (Exception e) {
return "catch ...";
} finally {
return "finally ..."; //got as result
}
}
}
My question is why there are no compile time errors. When I have the return statement in my finally block, it is bound to return from finally instead of try and catch block. I tried to compile this code with -Xlint option, it gives a warning as.
warning: [finally] finally clause cannot complete normally
It does not give a compilation error because it is allowed by the Java Language Specification. However, it gives a warning message because including a return statement in the finally block is usually a bad idea.
What happens in your example is the following. The return statement in the try block is executed. However, the finally block must always be executed so it is executed after the catch block finishes. The return statement occurring there overwrites the result of the previous return statement, and so the method returns the second result.
Similarly a finally block usually should not throw an exception. That's why the warning says that the finally block should complete normally, that is, without return or throwing an exception.
This is described in the Java Language Specification:
§14.17
Abrupt completion of a finally clause can disrupt the transfer of
control initiated by a return statement.
§14.20.2
If execution of the try block completes normally, then the finally
block is executed, and then there is a choice:
If the finally block completes normally, then the try statement completes normally.
If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S.
If execution of the try block completes abruptly for any other reason
R, then the finally block is executed, and 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).
There are no compile time error since only 1 and exactly 1 of return statement will actually return the control back to calling code.
As explained #Hoopje, return within try or catch will execute first, their respective return statement will also execute. But just before returning the control back to calling code, it will execute the finally block. Now, this block also returns something, so this return overrides the previous one.
It's essentially the same as this:
public boolean someMethod(){
if(1 == 1){
return true;
}
return false;
}
It will not give a compilation error, although it will give a warning. The compiler will only give an error when there's a chance of no return statement being executed.
Brilliant Question.. According to my knowledge return statement of the try and catch block is transferred to finally if you have added finally block to your code. That's how its work.
So in this case all code lines are executing and you can try debugging. The all three blocks I tried below code.
public class Main {
public static void main(String[] args) {
System.out.println(foo());
}
static String foo() {
try {
throw new Exception();
} catch (Exception e) {
return "catch ...";
} finally {
return "finally ..."; //got as result
}
}
}
You can get the idea from below link.
Multiple returns: Which one sets the final return value?
Your code works fine because there is only one return statement in try, catch and finally blocks. Compilation error will occur if you try to write two return statements inside one of try, catch or finally blocks saying there is an unreachable return statement.
(For short answer- Read the bold and italic parts of the answer)
The execution flow as per the Java 8 docs. It provides you the details. You can infer execution of return statements based on the following.
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, then the finally block is
executed, and then there is a choice:
– If the finally block completes normally, then the try statement completes
normally.
– If the finally block completes abruptly for reason S, then the try statement
completes abruptly for reason S.
• If execution of the try block completes abruptly because of a throw of a value
V, then there is a choice:
– If the run-time type of V is assignment compatible with a catchable exception
class of any catch clause of the try statement, then the first (leftmost) such
catch clause is selected. The value V is assigned to the parameter of the
selected catch clause, and the Block of that catch clause is executed.
Then there is a choice:
› If the catch block completes normally, then the finally block is executed.
Then there is a choice:
» If the finally block completes normally, then the try statement
completes normally.
» If the finally block completes abruptly for any reason, then the try
statement completes abruptly for the same reason.
› If the catch block completes abruptly for 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).
– If the run-time type of V is not assignment compatible with a catchable
exception class of any catch clause of the try statement, then the finally
block is executed.
Then there is a choice:
› If the finally block completes normally, then the try statement completes
abruptly because of a throw of the value V.
› If the finally block completes abruptly for reason S, then the try statement
completes abruptly for reason S (and the throw of value V is discarded and
forgotten).
• If execution of the try block completes abruptly for any other reason R, then the
finally block is executed, and 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 explanation is clear in this link- javaDoc
try running this:
it will print: 1, 2, 3 and then throw a division by zero Exception
public class Demo {
public static void main(String[] args) {
System.out.println(foo());
}
public static String print(int a){
System.out.println(a);
return String.valueOf(a/0);
}
static String foo() {
try {
return print(1);
} catch (Exception e) {
return print(2);
} finally {
return print(3);
}
}
}
This was an interview question:
public class Demo {
public static void main(String[] args) {
System.out.println(foo());
}
static String foo() {
try {
return "try ...";
} catch (Exception e) {
return "catch ...";
} finally {
return "finally ..."; //got as result
}
}
}
My question is why there are no compile time errors. When I have the return statement in my finally block, it is bound to return from finally instead of try and catch block. I tried to compile this code with -Xlint option, it gives a warning as.
warning: [finally] finally clause cannot complete normally
It does not give a compilation error because it is allowed by the Java Language Specification. However, it gives a warning message because including a return statement in the finally block is usually a bad idea.
What happens in your example is the following. The return statement in the try block is executed. However, the finally block must always be executed so it is executed after the catch block finishes. The return statement occurring there overwrites the result of the previous return statement, and so the method returns the second result.
Similarly a finally block usually should not throw an exception. That's why the warning says that the finally block should complete normally, that is, without return or throwing an exception.
This is described in the Java Language Specification:
§14.17
Abrupt completion of a finally clause can disrupt the transfer of
control initiated by a return statement.
§14.20.2
If execution of the try block completes normally, then the finally
block is executed, and then there is a choice:
If the finally block completes normally, then the try statement completes normally.
If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S.
If execution of the try block completes abruptly for any other reason
R, then the finally block is executed, and 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).
There are no compile time error since only 1 and exactly 1 of return statement will actually return the control back to calling code.
As explained #Hoopje, return within try or catch will execute first, their respective return statement will also execute. But just before returning the control back to calling code, it will execute the finally block. Now, this block also returns something, so this return overrides the previous one.
It's essentially the same as this:
public boolean someMethod(){
if(1 == 1){
return true;
}
return false;
}
It will not give a compilation error, although it will give a warning. The compiler will only give an error when there's a chance of no return statement being executed.
Brilliant Question.. According to my knowledge return statement of the try and catch block is transferred to finally if you have added finally block to your code. That's how its work.
So in this case all code lines are executing and you can try debugging. The all three blocks I tried below code.
public class Main {
public static void main(String[] args) {
System.out.println(foo());
}
static String foo() {
try {
throw new Exception();
} catch (Exception e) {
return "catch ...";
} finally {
return "finally ..."; //got as result
}
}
}
You can get the idea from below link.
Multiple returns: Which one sets the final return value?
Your code works fine because there is only one return statement in try, catch and finally blocks. Compilation error will occur if you try to write two return statements inside one of try, catch or finally blocks saying there is an unreachable return statement.
(For short answer- Read the bold and italic parts of the answer)
The execution flow as per the Java 8 docs. It provides you the details. You can infer execution of return statements based on the following.
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, then the finally block is
executed, and then there is a choice:
– If the finally block completes normally, then the try statement completes
normally.
– If the finally block completes abruptly for reason S, then the try statement
completes abruptly for reason S.
• If execution of the try block completes abruptly because of a throw of a value
V, then there is a choice:
– If the run-time type of V is assignment compatible with a catchable exception
class of any catch clause of the try statement, then the first (leftmost) such
catch clause is selected. The value V is assigned to the parameter of the
selected catch clause, and the Block of that catch clause is executed.
Then there is a choice:
› If the catch block completes normally, then the finally block is executed.
Then there is a choice:
» If the finally block completes normally, then the try statement
completes normally.
» If the finally block completes abruptly for any reason, then the try
statement completes abruptly for the same reason.
› If the catch block completes abruptly for 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).
– If the run-time type of V is not assignment compatible with a catchable
exception class of any catch clause of the try statement, then the finally
block is executed.
Then there is a choice:
› If the finally block completes normally, then the try statement completes
abruptly because of a throw of the value V.
› If the finally block completes abruptly for reason S, then the try statement
completes abruptly for reason S (and the throw of value V is discarded and
forgotten).
• If execution of the try block completes abruptly for any other reason R, then the
finally block is executed, and 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 explanation is clear in this link- javaDoc
try running this:
it will print: 1, 2, 3 and then throw a division by zero Exception
public class Demo {
public static void main(String[] args) {
System.out.println(foo());
}
public static String print(int a){
System.out.println(a);
return String.valueOf(a/0);
}
static String foo() {
try {
return print(1);
} catch (Exception e) {
return print(2);
} finally {
return print(3);
}
}
}
This question already has answers here:
Exception thrown in catch and finally clause
(12 answers)
Closed 9 years ago.
When I am executing following code
1. public class test {
2. public static void main(String[] args) {
3. try {
4. int i = 10 / 0;
5. } catch (Exception e) {
6. int j = 10 / 0;
7. } finally {
8. int k = 10 / 0;
9. }
10. }
11. }
I am getting an error:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at test.main(test.java:8)
I am not getting the reason why JVM is throwing exception from main() and not the catch block.
If you follow the step-by-step description of a try-catch-finally in the JLS, you see that (in summary) if catch throws an exception then finally is executed and (emphasis mine):
If the catch block completes abruptly for reason R, then the finally block is executed.
If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).
So the exception thrown by the catch block (which is executed before the finally block) is discarded and the reported exception is the one thrown in the finally block.
Because in every block - try/catch/finally you have a division by zero. Add another try-catch block inside catch and report an error in catch.
For example:
public class test {
public static void main(String[] args) {
try {
int i = 10 / 0;
} catch (Exception e) {
try {
int j = 10 / 0;
} catch (Exception e) {
// report an error here - do not do any business logic
}
} finally {
int k = 10 / 0;
}
}
}
One interesting thing to note is that, if you comment your code in the finally statement, the ArithmeticException thrown will concern the code in your catch statement.
I believe what's happening here is that the Exception that should be thrown in your catch statement is ignored, because an Exception is thrown in your finally statement.
The exception
in } catch (Exception e) {
int j = 10 / 0;
}
will be thrown to finally block, if you remove finally block, you will got an
Exception in thread "main" java.lang.ArithmeticException: / by zero
at test.main(test.java:6)
All exception in catch block will be thrown to finally block
also finally block will be executed any way
try
{
System.out.println("Try block 1");
int i = 10 / 0; //First Exception
System.out.println("Try block 2");
} catch (Exception e) { //Catched the first Exception
System.out.println("Catch block 1");
int j = 10 / 0; //Again Exception --> Who will catch this one
System.out.println("Catch block 2");
} finally {
System.out.println("finally block 1");
int k = 10 / 0; //Again Exception --> Who will catch this one
System.out.println("finally block 2");
}
If an exception occurs within the try block, that exception is handled by an exception handler associated with it. To associate an exception handler with a try block, you must put a catch block after it.
You associate exception handlers with a try block by providing one or more catch blocks directly after the try block.
Each catch block is an exception handler and handles the type of exception indicated by its argument
The finally block always executes when the try block exits.
In Java Exception Handling, no matter the exception is caught or not, but if you have used finally block, it would always get executed.
Hence, what you are doing in your code is-
Throwing exception object from main()
Catching exception in catch block
Throwing exception caught in catch block to the finally block (it would get executed anyway!)
In this code, either you use only catch or only finally, to get proper result.
and, since you want exception to be caught in catch, omit finally, just use catch.
Good luck!
public class Abc {
public static void main(String args[]) {
System.out.println(Abc.method());
}
static int method() {
try {
throw new Exception();
}
catch(Exception e) {
throw new Exception();
}
finally {
return 4;
}
}
}
Why is the return value 4?
That's the way finally works. The snippet
try {
throw new Exception();
} catch(Exception e) {
throw new Exception();
}
will complete abruptly, but the finally clause will kick in and when it returns it discards the original reason for completing the statement.
This is explained in section Blocks and Statements in the Java Language Specification. I've highlighted the relevant path in your situation:
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, then the
finally block is
executed, and then there is a choice:
... If execution
of the try block
completes abruptly because of a
throw of a value
V, then there is a choice:
If
the run-time type of V is
assignable to the parameter of any
catch clause of the
try statement, then the
first (leftmost) such
catch clause is selected.
The value V is assigned to the
parameter of the selected
catch clause, and the
Block of that
catch clause is executed.
Then there is a choice:
If the
catch block completes
normally, then the
finally block is
executed. Then there is a choice:
... If the
catch block completes
abruptly for 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).
If the run-time type of V
is not assignable to the parameter of
any catch clause of the
try statement, then the
finally block is
executed. Then there is a choice:
...
If execution of the
try block completes
abruptly for any other reason
R, then the
finally block is
executed. Then there is a choice:
...
You should never return from a finally block. This is very bad practice. See Java try-finally return design question and Does finally always execute in Java?.
There are several questions on StakOverflow that explain this.
To make it simple: if you put a return or a throw statement in a finally clause this is the last action of your method. Generally speaking this is a bad practice though.
Finally will always return 4. The finally block will always execute regardless of any exception that is throw in the try and catch blocks.
The fact that the finally block returns a value causes the thrown exception to be swallowed, so it wont propagate out of the method.