Ok, calm down already – I’m not going to take your return statement away. It’s a nice little statement that gets rarer and rarer, mostly because many modern languages allow for implicit return values, e.g. in Scala, everything is an expression and the last expression of a method is its return value – except when it isn’t. You dont need to write an explicit return statement anymore, so our laziness takes over and we omit it.
And I’m not argueing that a finally block is a bad thing – quite the contrary. Even in the age of try-with-resources and autoclose closures, a well-crafted finally block is a beautiful piece of code at its right place.
But put the two together and you’ve got a recipe for desaster, at least in Java (try it in your language of choice with care). Let’s have a look at code:
public void doSomething() { try { throw new Error("drama!"); } finally { // dispose resources here } }
Ok, I could have spared you the drama of an Error and just thrown a RuntimeException (or a declared and checked Exception), but it’ll soon illustrate the effect all the better.
First, the code does exactly what it should: if you call the method, you’ll get to catch an Error and all resources that were used inside the method are cleaned up right before you catch it. And since the method has no return value, you don’t miss out there.
But what if I want to give one of those endangered return statements a new home and insert it into the finally block?
public void doSomething() { try { throw new Error("drama!"); } finally { // dispose resources here return; } }
Not much has changed. I’m still not missing any return value and the Error still gets thrown. The resources are cleaned up quite as thorough as before, but something important has changed: You won’t ever see the Error. You won’t catch it because it gets eaten by that return statement at the end of the finally block.
So in short: return statements are hungry little beasts that will eat your Throwables if you corral them inside a finally block.
No wonder nobody wants to have them in their code if they behave like that.
Oh, and rest assured that you will be warned: All modern IDEs will point you to the inevitable desaster waiting to happen, if only with a compiler warning.
But where do Throwables go when they got eaten? Good question. They don’t show up on any UncaughtExceptionHandler, they don’t even stay in memory. Probably, they just are digested, never to be seen again.
If you don’t regard return statements as a little more dangerous now, you probably also raise switch-statements for fun.