Home of the AlmostImplementedException

Why is it bad to use return, break or continue in a finally block

For my current customer I develop tools and plugins for Eclipse and TTCN3 ( a hardware testing language) in Java and help the development team to improve the coding-style with code reviews on a weekly basis.
The question above occurred on the review last Friday and I thought it’s worth sharing, although C# don’t allow it anyway. (BTW, this is one of the things I like about C# the most.)

So, why is it bad style?
– Others don’t expect a return, break or continue in a finally-block. => Its harder to understand the code and therefore not CleanCode.
– A return value should be final and not changed afterwards. => A return in finally overwrites any prior return value.
– A finally block should not change the behavior of the code. => Continue and break do that.

And that are the reasons why you can’t do it in C#. But luckily you can try the same in Java. Therefore I will give a few example of bad coding-style and (not so) funny results.

This one is easy and everyone should get it. The returned value is false.

This one is a little trickier. Normally we return the current value of “i” which is 0. But this time the break interrupts the for-loop and therefore the return too. The returned value is -1.

Now we have an infinite loop which should be interrupted with the return. But in fact, its not. Even the compiler will tell you that return -1; is never reached. The code will compile if you remove this line.
But then you have to deal with infinity….

And here is the final example. Try to get the result on your own, before you look at the conclusion. Which value is returned?

Yeah right! None! You’ll get an exception.
In Java 1.6 and prior its: java.lang.VerifyError: (class: TestTest, method: check2 signature: ()I) Inconsistent stack height 0 != 2
and in Java 1.7: java.lang.VerifyError: Expecting a stackmap frame at branch target 11 in method TestTest.check2()I at offset 11

Both are right and a little disturbing, ’cause they mean that the code optimizer put the finally-code-block directly behind the loop-condition-check. => After the loop is finished another continue is executed and the loop-condition is checked again.

If we change this example just a little bit in adding a System.out, the behavior changes dramatically:

What happens now? The function returns -1! Because the continue is executed after the try-block, which is only called when the loop-condition is matched.

Now it should be clear why its not wise to use break, continue or return in a finally block.

Share :

, , , ,

Leave a Reply