Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Agile forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

finally clause...

 
Pat Peg
Ranch Hand
Posts: 195
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I was playing around with some code and encoutered a warning "finally block does not complete normally" and I guess I am a bit confussed. Here is a code snipit. can someone enlighten me.

My thinking was this...regardless of what happens (errors or no errors) I want the return value sent back. I read on some sites where they said you shouold never put a return in the finally but I don't see the reason. In fact, it seems wrong not to. Why is this not correct?
 
Nigel Browne
Ranch Hand
Posts: 703
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The finally block should only be used for clean up code for example closing database connection e.t.c.
You should remove your finally block and end you method with
 
John Smith
Ranch Hand
Posts: 2937
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I read on some sites where they said you shouold never put a return in the finally but I don't see the reason.

The reason is that the return from the finally block will mask an exception thrown from the try block. That exception (along with the stack trace) will be lost forever, which will make it very difficult to diagnose and fix a potential problem. Instead of hiding the exceptions (or hiding from the exceptions), the code must process them in some sensible manner.
 
Philip Heller
author
Ranch Hand
Posts: 119
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
How exactly did you get that "finally block does not complete normally" warning? I added some declarations to your code, and got the followingm which compiled just fine:



But I definitely don't recommend this coding style. Here's why:

1) This code catches runtime exceptions. That's an inefficient way to check preconditions.

2) "Handling of the finally block is rather complex." That's a direct quote from the Java Language Spec. Now if I think something's complex, that might not mean much, but if Gosling thinks it's complex, then it's definitely complex. If you use a finally block when a simple return statement will do, you introduce mystery and complexity. Those are good things when you're writing a story but it's best to avoid them in your code.

So what's good for? What value does it add? If all exceptions raised in the try and catch blocks are handled by the catch blocks, then a finally block adds no value. The value comes in when an exception is handled by the current method's caller, or some higher level of the calling sequence. In this case the finally block executes before the exception is handled by the higher level. Here's a simple example:



The output is:
thrower() finally
test() caught IOException

You would get the same result if test() had some catch blocks for exception types other than IOException.

If you're not in this kind of situation (Exceptions handled outside of the current method), there's no value to the catch block.

There's an animated illustration of the try/catch mechanism in Chapter 11 of "Ground-Up Java". But I decided not to include the finally mechanism because I didn't want to overwhelm people.
 
Pat Peg
Ranch Hand
Posts: 195
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yea, I was just looking more for a "why it is bad to do the return statement in there" answer. I understand that they are saying you should only do clean up work but what is wrong by returning from that point?
 
Pat Peg
Ranch Hand
Posts: 195
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Oh, never mind...I know see. I was only looking at the first reply when I added the above comment-thanks-I get it now.
 
Ilja Preuss
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by John Smith:
The reason is that the return from the finally block will mask an exception thrown from the try block. That exception (along with the stack trace) will be lost forever, which will make it very difficult to diagnose and fix a potential problem. [/QB]


And not only Exceptions, but even Errors! You would even hide something serious like an OutOfMemoryError, as far as I know!
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic