Why won't main method catch the uncaught exception from catch block - java

I came up with this example while studying mock exams for OCPJP certification,
(from http://www.certpal.com version 1.6 exam part 3, Flow Control, Question number 8)
public class Oak
{
public static void main(String args[])
{
try
{
Integer i =null;
i.toString();
}
catch (Exception e)
{
try
{
System.out.println("One ");
Integer i =null;
i.toString();
}
catch (Exception x)
{
System.out.println("Two ");
Integer i =null;
i.toString();
}
finally
{
System.out.println("Three ");
Integer i =null;
i.toString();
}
}
finally
{
System.out.println("Four ");
}
}
}
I am fully aware that finally blocks always execute unless there is a System.exit(), so I traced the program and decided that it will have an output like this
One Two Exception in thread "main" java.lang.NullPointerException Three Exception in thread "main" java.lang.NullPointerException Four
However, it turns out the correct output is (according to the site and Eclipse debugging)
One Two Three Four Exception in thread "main" java.lang.NullPointerException
What I'm not understanding is, where did the exception which occurs in catch block with "Two" go?
There is no catch block underneath that, shouldn't it be thrown by the main thread too? Because it's not catched?

That exception is effectively lost - if a finally block throws an exception, any exception which was in the course of propagating becomes irrelevant, and the result of the finally block is the new exception.
Likewise if you return in a finally block, then that overall try/catch/finally will never throw an exception.
See section 14.20.2 of the Java Language Specification for details. In particular, various bits like this:
If the finally block completes abruptly for any reason, then the try statement completes abruptly for the same reason.

Related

Exception hierarchy/try-multi-catch

try {
throw new FileNotFoundException();
} catch (IOException e) {
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
Can someone tell me why the second catch block is not considered as unreachable code by the compiler? But in the following case:
try {
throw new FileNotFoundException();
} catch (Exception e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
The second catch block is considered unreachable?
After all, FileNotFoundException comes under IOException, just as it comes under Exception.
Edit Please clarify:
The compiler will know an exception is thrown by a method based on the method's throws clause. But it may not necessarily know the specific type of exception (under that class of exception). So if a method throws exception 'A', compiler won't know if the actual exception is 'A' or a subtype of 'A' because this is only determined at runtime. The compiler however will know that an exception of type 'X' is never thrown, so giving a catch block for X is erroneous. Is this right?
The compiler cannot assume that the only possible exception thrown from your try block will be a FileNotFoundException. That's why it doesn't consider the 2nd catch block to be unreachable in your first code sample.
What if, for some unknown reason, a RuntimeException gets thrown while creating the FileNotFoundException instance (entirely possible)? What then?
In your first code sample, that unexpected runtime exception would get caught by the 2nd catch block, while the 1st block would take care of the FileNotFoundException if it gets thrown.
However, in your 2nd code sample, any and all exceptions would get caught by the 1st catch block, making the 2nd block unreachable.
EDIT:
To better understand why the catch(Exception e) block in your first code is not considered unreachable by the compiler, try the following code, and notice how the the 2nd catch is definitely reachable:
public class CustomIOException extends IOException {
public CustomIOException(boolean fail) {
if (fail) {
throw new RuntimeException("the compiler will never know about me");
}
}
}
public static void main(String[] args) {
try {
throw new CustomIOException(true);
} catch(IOException e) {
System.out.println("Caught some IO exception: " + e.getMessage());
} catch(Exception e) {
System.out.println("Caught other exception: " + e.getMessage());
}
}
Output:
Caught other exception: the compiler will never know about me
TL;DR
The compiler considers that FileNotFoundException() may not be the only Exception thrown.
Explaination
JLS§11.2.3 Exception Checking
A Java compiler is encouraged to issue a warning if a catch clause can
catch (§11.2) checked exception class E1 and the try block
corresponding to the catch clause can throw checked exception class
E2, a subclass of E1, and a preceding catch clause of the immediately
enclosing try statement can catch checked exception class E3 where E2
<: E3 <: E1.
That means that if the compiler considers that the only exception possibly thrown by your catch block is a FileNotFoundException(), it will warn you about your second catch block. Which is not the case here.
However, the following code
try{
throw new FileNotFoundException();
} catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e){ // The compiler warns that all the Exceptions possibly
// catched by IOException are already catched even though
// an IOException is not necessarily a FNFException
e.printStackTrace();
} catch (Exception e){
e.printStackTrace();
}
This happens because the compiler evaluates the try block to determine which exceptions has the possibility to be thrown.
As the compiler does not warn us on Èxception e, it considers that other exceptions may be thrown (e.g RunTimeException). Since it is not the compiler's work to handle those RunTimeExceptions, it lets it slip.
Rest of the answer is intersting to read to understand the mechanism behind exception-catching.
Schema
As you may see, Exception is high in the hierarchy so it has to be declared last after IOException that is lower in the hierarchy.
Example
Imagine having an IOException thrown. As it is inherited from Exception, we can say IOException IS-A Exception and so, it will always be catched within the Exception block and the IOException block will be unreachable.
Real Life Example
Let's say, you're at a store and have to choose pants. The seller tells you that you have to try the pants from the largest ones to the smallest ones and if you find one that you can wear (even if it is not your size) you must take it.
You'll find yourself buying pants too large for your size and you'll not have the chance to find the pants that fits you.
You go to another store : there, you have the exact opposite happening. You can choose your pants from smallest to largest and if you find one you can wear, you must take it.
You'll find yourself buying pants at your exact size.
That's a little analogy, a bit odd but it speaks for itself.
Since Java 7 : multi-catch
Since Java 7, you have the option to include all the types of Exceptions possibly thrown by your try block inside one and only catch block.
WARNING : You also have to respect the hierarchy, but this time, from left to right.
In your case, it would be
try{
//doStuff
}catch(IOException | Exception e){
e.printStackTrace();
}
The following example, which is valid in Java SE 7 and later,
eliminates the duplicated code:
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
The catch clause specifies the types of exceptions that the block can
handle, and each exception type is separated with a vertical bar (|).
First case:
catch (IOException e) { // A specific Exception
e.printStackTrace();
}
catch (Exception e) { // If there's any other exception, move here
e.printStackTrace();
}
As you can see, first IOException is catched. This means we are aiming at just one specific exception. Then in second catch, we aim for any other Exceptions other than IOException. Hence its logical.
In second:
catch (Exception e) { // Move here no matter whatever exception
e.printStackTrace();
}
catch (IOException e) { // The block above already handles *Every exception, hence this won't be reached.
e.printStackTrace();
}
We catched any exception (whether its IOException or some other Exception), right in the first block. Hence second block will not be reached because everything is already included in first block.
In other words, in first case, we aim at some specific exception, than at any other exceptions. While in second case, we first aim at all/any Exception, than at a specific exception. And since we already dealt will all exceptions, having a specific exception later won't make any logical sense.

Try-catch-finally order of execution appears to be random [duplicate]

This question already has an answer here:
Why does the execution order between the printStackTrace() and the other methods appear to be nondeterministic?
(1 answer)
Closed 7 years ago.
I am trying to understand how the try-catch-finally execution flow works. There are a couple of solutions from Stack Overflow users regarding their execution flow.
One such example is:
try {
// ... some code: A
}
catch(...) {
// ... exception code: B
}
finally {
// finally code: C
}
Code A is going to be executed. If all goes well (i.e. no exceptions get thrown while A is executing), it is going to go to finally, so code C is going to be executed. If an exception is thrown while A is executed, then it will go to B and then finally to C.
However, I got different execution flows when I tried it:
try {
int a=4;
int b=0;
int c=a/b;
}
catch (Exception ex)
{
ex.printStackTrace();
}
finally {
System.out.println("common");
}
I am getting two different outputs:
First output:
java.lang.ArithmeticException: / by zero
at substrings.main(substrings.java:15)
lication.AppMain.main(AppMain.java:140)
common
However, when I ran the same program for the second time:
Second output:
common
java.lang.ArithmeticException: / by zero
at substrings.main(substrings.java:15)
What should I conclude from this? Is it going to be random?
printStackTrace() outputs to standard error. System.out.println("common") outputs to standard output. Both of them are routed to the same console, but the order in which they appear on that console is not necessarily the order in which they were executed.
If you write to the same stream in both catch block and finally block (for example, try System.err.println("common")), you'll see that the catch block is always executed before the finally block when an exception is caught.
Exception's printstacktrace() method source code(defined in Throwable class)
public void printStackTrace() {
printStackTrace(System.err);
}
The formatting of output occurs because your are using standard output stream through System.out.printlnand exception occurs System.err stream
Try having a variable which will check exceptions and print in same error console if exception occurs :-
boolean isException = false;
try {
int a=4;
int b=0;
int c=a/b;
}
catch (Exception ex)
{
isException = true
ex.printStackTrace();
}
finally {
if(isException){
System.err.println("common");
}else{
System.out.println("common");
}
}

Java - Catching Exceptions Using Class Exception [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have to: create a code that demonstrates how various exceptions are caught: using the code template of:
catch (Exception exception)
Thanks for all of the helpful comments.
I've revised my code:
package exception;
import java.util.Scanner;
import java.io.*;
public class Exception
{
public static void main(String args[])
{
try
{
int a[] = new int[10];
System.out.println("Access element three :" + a[11]);
// The reason this is an exception is because there is no element 11 of the array. It only has 10.
}
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("Exception thrown :" + e);
// This should print out whatever number was requested for a[e]
}
System.out.println("Out of the block");
// Once the exception is caught, this statement will be printed.
}
}
Output:
run:
Exception thrown :java.lang.ArrayIndexOutOfBoundsException: 11
Out of the block
BUILD SUCCESSFUL (total time: 1 second)
Now my question is: Is the format done correctly? The problem requires that I use
catch (Exception exception).
I'm not sure if that's what I did - If not how can I?
Once again, thanks everyone.
The problem is with the syntax of your try-catch block.
It should be as follows:
try {
//Here goes code that might throw an exception.
}
catch(Exception e)
{
//Here goes code to handle if an exception was thrown in the try block.
}
I'm assuming your assignment hander-outer wants you to not just throw and exception with "throw new java.lang.Exception();" But instead to write some code that might throw an exception.
If you want the code to work the way you're doing it, it'll look like this:
try {
java.lang.Exception exception = new java.lang.Exception();
throw exception;
}
catch(Exception e)
{
System.out.println("I caught one!, Here's it's info: ");
e.printStackTrace();
}
However, if you want to do it the correct way, it'll look something like this:
try {
int number = 500;
int result = number / 0;
//This will throw an exception for dividing by zero.
int[] array = new int[10];
int bad = array[11];
//This will throw an ArrayIndexOutOfBoundsException
}
catch(Exception e)
{
System.out.println("I caught one! Here's some info: ")
e.printStackTrace();
}
Of course, with the code above, as soon as the first exception is thrown (by dividing by zero), the catch block will catch it and break out of the try block, so the next bad piece of code isn't ever executed.
I recommend looking here for learning what you need to know for this assignment:
https://docs.oracle.com/javase/tutorial/essential/exceptions/try.html
Also here:
https://docs.oracle.com/javase/tutorial/essential/exceptions/handling.html
And here as well:
http://docs.oracle.com/javase/tutorial/essential/exceptions/
Good Luck!
EDIT
In your catch block, you can use "System.exit(1);" Which will stop your program and have it return 1, which means that it ended its execution with an error.
However, let's say you're wanting to get a user to enter their age. You can prompt them in a try block and in the case that they enter a negative number, you could catch it with an exception and prompt again until they enter a positive number. In that case, you wouldn't want to use System.exit(1) because then your program would stop when it could keep going, all because a user gave a bad input.
That isn't a good example because you shouldn't handle such trivial things, like negative numbers, with an exception. But the idea is the same. If you want your code to continue on, you'll want to handle the error and continue. The only time to use "System.exit(1);" is if your program can't fix the error given, or if your program only did one task and that task couldn't be completed with the given input or encounters an error in doing that task.
This has included some things the other answer forgot, like scriptability (it's a good thing!)
package exception;
//import java.util.Scanner; (unused import)
import java.lang.Exception;
public class ExceptionTester {
public static void main(String[] args) {
try {
throw new Exception("Error Message Here");
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
};
}
}

Unhandled Java exception execute remainder of method?

I was responding to a slough of basic Java practice test questions and the correct answer to the following question slipped past me while taking the test.
Question: "If an exception is not caught, the finally block will run and the rest of the method is skipped - TRUE or FALSE?"
I am attempting to prove out the answer with the ThrowTest class (pasted at bottom) but I find Java exception handling to be somewhat unfamiliar. I compile the class as is with the ArrayIndexOutOfBoundsException portion of the catch block commented out. I then execute the class without passing an input parm thus creating an exception (the ArrayIndexOutOfBoundsException exception) . I would expect the final System.out.println would not execute and indeed it does not.
I find if I un-comment the ArrayIndexOutOfBoundsException catch block and recompile, the class then catches that specific error at run time and executes the "Rest of method" println at bottom. So, does my code prove the rest of "the rest of the method is skipped" or do I have to test it from a method other than the main method? Maybe there is a more straightforward method of testing it.
public class ThrowTest
{
public static void main(String[] args)
{
try
{
String anyString = args[0];
System.out.println("Try code executes");
}
catch(SecurityException e) //any old exception
{
System.err.println ("Error: SecurityException. ");
e.printStackTrace();
}
/* begin comment
catch(ArrayIndexOutOfBoundsException e)
{
System.err.println("Error: Caught ArrayIndexOutOfBoundsException. ");
e.printStackTrace();
}
end comment */
finally
{
System.out.println("finally block executes!");
}
System.out.println("Rest of method executes!");
}
}
Regardless of what exception is thrown a finally block will always execute (barring any strange situations like out of memory), so given the following
try {
// do some code
}
catch (SomeException e) {
// exception handling
}
finally {
doFinallyStuff();
}
doOtherStuff();
doFinallyStuff will always execute here. But doOtherStuff will only execute under the following conditions:
No exceptions are thrown
SomeException is thrown and the catch block does not rethrow the exception up the chain
If another exception is thrown in the try block that is not handled by the catch block, doFinallyStuff will still execute, but doOtherStuff will not
Your code is indeed proving that everything works as you described. When you catch an exception, then the rest of the method thereafter executes. If you let the method throw the exception, its execution halts immediately. Either way, the finally block will always execute.

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