Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Developer poll. return within finally: I need your opinons

0 views
Skip to first unread message

duncan_strang

unread,
Mar 3, 2004, 5:54:31 AM3/3/04
to
Hi

I'd be interested to hear what developers think about the following
issue that has been doing the rounds here at work.

Say we have the following code

public int confused(){
String foo = "bar";
int val = -1;
try{
val = Integer.parseInt(foo);
}
catch(Exception ex){
ex.printStackTrace();
}
finally{
System.out.println("This always executes");
return val;
}
}

The question is:

What do you think about inserting a return within a finally block ?

The language spec appears ambiguous, also different versions of the
compiler behave differently, for example.

Compiling the above with j2se 1.4.1_02-b06 gives no warnings.

Compiling with j2se 1.4.2-b28 gives the following warning

Test.java [38:1] warning: finally clause cannot complete normally
}
^
1 warning
Finished Test.

I've read various articles and specs that seem to indicate that the
jvm handles the stack correctly (in terms of return addresses for
example) but the compiler still raises the warning.

All opinions gratefully accepted

Cheers
Duncan L.Strang

Ryan Stewart

unread,
Mar 3, 2004, 8:01:37 AM3/3/04
to
<Duncan Strang> wrote in message
news:c0bb40tkqplkvgbie...@4ax.com...
I'd consider that the least preferable way to do it. Why return from a
finally block when you can get exactly the same result by setting the
variable within the finally and returning *after* it? It could also cause
problems if someone less knowledgable has to maintain this code later on.
Question for you: if you put a return statement in the try block *and* in
the finally block, what happens? If you don't know, why would you expect
someone less experienced to know? And if you do know, same question. The
answer is that the finally block will be executed and that return value will
be used. The return in the try block is basically ignored.


duncan_strang

unread,
Mar 3, 2004, 9:11:31 AM3/3/04
to

Ryan, calm down, I wasn't suggesting it was the correct way to do
things I was simply asking for opinions ... I guess you are a 'no'
then

Rgds
Duncan
>

Manavendra Gupta

unread,
Mar 3, 2004, 10:28:53 AM3/3/04
to
I dont think its a good idea to return a value from the finally block, for
several reasons:
+ from what i understand of the spec, you use finally for any resource
free-up (closing any socket or database connections )
+ again, the spec guarantees finally block will be executed, but thats not
the most obvious place other reading your code will look at, to find the
return values.
+ returning a value from the finally block, IMO, gives a false impression
that everything went fine, that there were no exceptions. if you return a
value from a finally block then i'm sure you will be examining the value in
the caller method to see what happened - and you'd have an intrinsic "logic"
that "-1" (in your example), means something went wrong and take an
alternative action. this approach rings a bells of structured programming
days, doesn't it? why not return a value only if everything is alright (from
within the try block), and throw a typed exception if an exceptional
situation occured?

I believe, the key here is to question the very motive of returning a value
from a finally block.


<Duncan Strang> wrote in message
news:c0bb40tkqplkvgbie...@4ax.com...

Chris Uppal

unread,
Mar 3, 2004, 11:54:47 AM3/3/04
to
Duncan Strang wrote:

> What do you think about inserting a return within a finally block ?
>
> The language spec appears ambiguous, also different versions of the
> compiler behave differently, for example.

I think that it's legal and unambiguous Java. But the warning might be
justified by code like:

public int moreConfused()
{
try
{
return 22;
}
finally
{
return 33;
}
}

which might not be expected to return 33, but it does.

-- chris


Ryan Stewart

unread,
Mar 3, 2004, 12:34:24 PM3/3/04
to
<Duncan Strang> wrote in message
news:pppb40d0htokno2s6...@4ax.com...

Calm down? I'm fine. And yes, that was a no for the reasons I listed. You
asked for opinions, you got one. I'd consider it acceptable from a logical
point of view. In fact, I was surprised to learn you got a warning from it.
However, the possible cons outweigh the pros considerably, I think.


John C. Bollinger

unread,
Mar 3, 2004, 3:45:58 PM3/3/04
to
Duncan wrote:

Section 14.1 of the Language Spec (2nd Ed.) covers normal vs. abrupt
completion of statements in general, section 14.16 discusses all aspects
of the return statement, and section 14.19 discusses all aspects of
try-catch-finally.

Return statements by definition never complete normally, therefore the
compiler warning is valid. Perhaps the question is whether or not it is
useful -- I think it is. As Chris Uppal noted, the behavior of this
construct and similar are well defined. That doesn't mean that their
use is good practice, however. In the first place, implementation bugs
(i.e. compiler / VM bugs in this case) tend to live in little corners
like this, and it's no fun to troubleshoot a failure of your product
that turns out to live in one of those places. More importantly, it is
unwise to write code whose correct interpretation by another human
depends on knowledge of such fine details of the language -- you are
asking for maintenance problems down the road.

The precise construct you provided isn't so bad, but small variations
rapidly become confusing. For instance, what if the try block contains
one or more return statements? Or what if a throwable can go unhandled
by any catch block (e.g. as an OutOfMemoryError would do even in the
sample)? What if the finally block contains statements that might throw
an exception? What if the body of the try statement is long enough that
the presence of a return in the finally block isn't apparent? The
behavior is well defined in all these cases, but its interpretation may
be tricky.

The final nail with respect to the sample code specifically is that the
whole issue can be removed by simply moving the return statement after
the finally block. Behavior would be identical except in the case of a
Throwable other than an Exception being thrown from the try statement,
and arguably you would want to pass something like that on up the call
stack anyway.

Coming back to the compiler warning specifically, I repeat that I think
it useful and appropriate. It is advising you of a dubious programming
practice, hence it is a warning rather than an error. I would heed it.


John Bollinger
jobo...@indiana.edu

Neal Gafter

unread,
Mar 12, 2004, 1:02:59 AM3/12/04
to
Duncan wrote:
> What do you think about inserting a return within a finally block ?

I think it is an abomination, which is why I added the warning to javac.

> The language spec appears ambiguous, also different versions of the
> compiler behave differently, for example.

The language spec unambiguously allows it.

> Compiling the above with j2se 1.4.1_02-b06 gives no warnings.
>
> Compiling with j2se 1.4.2-b28 gives the following warning
>
> Test.java [38:1] warning: finally clause cannot complete normally
> }
> ^
> 1 warning
> Finished Test.

Mea culpa. The code for this warning wasn't supposed to go into the product
until 1.5.0. The latest (upcoming) patch for 1.4.2 will remove this warning.
But the warning will definitely be available in 1.5.0, though you'll have to ask
for it (-Xlint or -Xlint:finally). It is a warning, though. The language
allows it, but it is almost always bad style.

0 new messages