Wednesday, October 12, 2011

Try...Catch...Finally Puzzle Part II

In the first version, I think that the people missed the interesting stuff. So here is a modified version, of the code. Remember, the real question is what to expect. It will compile, and run. The two examples are more interesting.

NOTE: This is not an example of how to do something right. This is absolutely the wrong way to handle exception handling in Java.

Main.java



Main2.java


Here is the NetBeans project for the code: FinallyReturn2.zip

7 comments :

James C Bragg said...

Based on what we learned from the last JUG...

I believe that both will print out nothing..

The finally at least in JDK 7 will consume the exceptions..

James

Andy Bailey said...

To complete the answer.

You would expect the second NPE to be handled after the main method returns however the return statement causes the currently running Thread to need to exit (hence the return causing the private Thread.exit() method to execute immediately rather than closing the JVM down).

John Yeary said...

The trick is in the finally block. There is a return statement which short circuits the exception processing. The compiler recognizes that there is no way that an exception is thrown so it allows you to do anything you want. The scary part is that run time exceptions are discarded too. I have included the appropriate corner case remarks from the Java Language Standard (JLS) and the actual requirement.


http://java.sun.com/docs/books/jls/third_edition/html/statements.html

§14.20.2 Execution of try-catch-finally
...

If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and reason R is discarded).

...

Konrad Ciborowski said...

This behavior was described in Eckel's book some 110 years ago:

http://linuxtopia.org/online_books/programming_books/thinking_in_java/TIJ311_014.htm

Konrad Ciborowski
Kraków, Poland

John Yeary said...

These are great responses. I love it when there are links to other great materials.

Bruce does a great job in "Thinking in Java". He even keeps the material up to date.

Andy Bailey said...

This implies that your application could be brought to an abrupt halt without any indication as to why.

Your finally block in your main method has no code in it which should cause it to end abruptly and you have an unhandledException Handler ready in case something untoward happens deeper into your app.
However code in your main finally block causes something like OutOfMemoryError to be thrown in the current Thread and bang, application dies with no indication as to why.

So try {} finally {} is not as safe as one would expect and may have implications for try resources in JDK 7 leading to potential leaks.

John Yeary said...

The Java Language Specification (JLS) is very specific about the behavior.

Fundamentally, since we are discarding the Exception(s) being thrown at a point where we should handle them, there are no breadcrumbs to tell us what happened.

In this trivial example, the method continues executing and exits normally.

If this were used in the context of a larger application, the implications would be huge in terms of trying to find out why the application crashed.

Popular Posts