In defense of “only one
return
statement”
I read this on Bruce’s blog (Bruce of “Thinking in Java” fame). He is actually responding to a questioner who writes…
One inspection that some of our developers favor is: “There must only be a single return statement within each method”
PMD classifies this as a “controversial” inspection. They do not comment on why it is considered controversial.
[source…]
I recently picked Java back up again (and “Thinking in Java” … great book!), and when I first started back with it, this “rule” (only one return statement in a Java function) was so hard-wired into my head that I thought it would actually be a compiler error to have more than one return
statement in a function. This is not the case, but I still like to follow it for a variety of reasons. Please use the following sample code (the simplest and handiest bit of actual code I could find):
public String[] getParameters( String actionName )
{
TempContainer co = null;
co = (TempContainer)actionDefinitions.get( actionName );
String[] toReturn;
if( co != null )
{
toReturn = co.getParameters();
}
else
{
toReturn = new String[] { };
}
return toReturn;
}
…contrasting with this implementation:
public String[] getParameters( String actionName )
{
TempContainer co = null;
co = (TempContainer)actionDefinitions.get( actionName );
if( co != null )
{
return co.getParameters();
}
else
{
return new String[] { };
}
}
The purpose of the “getParameters” function is to return a list of parameters from an intermediate sub-object. At it’s heart it’s a simple convenience function, but why would you choose to write it one way versus the other?
I agree with Bruce’s statement that “all the rules in the world won’t prevent people who want to write bad code from writing bad code”, and I agree that the “no multiple return statements” rule might be a guideline that is broken more often than others, but there are several advantages I continually reap from having only one return
statement per function.
Number one is the ability to easily extend the functionality of an arbitrary function in the same manner that *nix users use pipes and filters. Just before my “return toReturn;” statement I know that I can insert a few more commands and not be “bitten” by an arbitrary return statement that happens on the previous page.
Example: Consider that I want to return a set of default parameters (“cow”, and “moo”) when no parameters were found. In the case of a single return, I simply add the following:
...
if( toReturn == null )
{
toReturn = new String[] { "cow", "moo" };
}
return toReturn;
}
In the case of multiple returns, I would have to analyze every code path that has a return and make sure they are “taken care of” properly (could lead to duplication). Trivial in this case, but in more complicated functions, it could be annoying. By committing to the single-return and the corresponding requirement that all my if
’s balance with my else
’s, and that program flow must properly “fall out” to the return statement, I find that my functions are generally much easier to maintain / extend.
To get the same level of ease / convenience from the multiple return statement implemenation, you might do something like the following:
public String getParameters( String actionName )
{
String toReturn = getParametersOriginal( actionName );
if( toReturn == null )
{
toReturn = new String[] { "cow", "moo" };
}
return toReturn;
}
private getParametersOriginal( String actionName ) { .... }
…which is the quickest, most-accurate way (in the general case) to ensure that all your cases are handled properly and every possible return
was returned from.
Finally, committing to a single return
simplifies debugging for me, as it becomes a lot easier to temporarily “override” what a function returns when you can do it in one spot. To temporarily always return “cow”, “moo”, simply do the following:
...
toReturn = new String[] { "cow", "moo" };
return toReturn;
}
…and you never have to worry about any prior returns short-circuiting your program flow. This also lets you easily put in post-conditions (or pre-conditions to your return), such as “all parameters returned must be capitalized” or something. I like sticking to a single return statement, and would recommend it highly to others for the general case.
01:14 CST | category / entries / links
permanent link | comments?