3

Is using an if coupled with an immediate return like in the example below an acceptable practise instead of having a if with a block of code inside {} ? Are these equivalent in practise or is there a disadvantage to one of the approaches ?

An example in Java:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

ServletContext sc = this.getServletContext();       

// Throw exception for fatal error (Servlet not defined in web.xml ?)
if( sc == null )
 return; // old-style programming
 // Careful with silent bugs ! Correct way of handling this is:
 // throw new RuntimeException( "BookDetail: ServletContext is null" );

BookList bookList = WebUtil.getBookList( sc );
James P.
  • 19,313
  • 27
  • 97
  • 155
  • 1
    It's always a style (religious) issue. I personally believe all functions should have one return statement. But, in the case of exceptions, well..... they are a good reason for an exception to that rule. (But, as I said, this is a holy war). – KevinDTimm Dec 11 '09 at 15:06
  • This seems to be a duplicate of this question http://stackoverflow.com/questions/639166/different-ways-of-writing-the-if-statement/639701#639701 – Jacob Adams Dec 11 '09 at 15:07
  • 2
    @Jacob: not even close. James isn't asking about how to put braces in a if statement, he's asking if it's ok to return early in a method. – Paul Tomblin Dec 11 '09 at 15:09
  • @Paul: Yes, I'm wondering if there was a real difference between the two. I sometimes have interesting conversations on things like this with a friend who's in industrial programming where reliability is very important. @Jacob: I've heard that example 4 of the curly brackets questions was a consequence of editors trying to save space in books. – James P. Dec 11 '09 at 15:24
  • 1
    It is interesting to note that those who disagree with early returns will still tend to use 'break' or 'continue' in a loop. I've run across a few who shun those as well, especially continue. To me, all of those constructs (especially early-return and continue) are about avoiding excessive nesting levels... which I like. – PSpeed Dec 11 '09 at 17:30

8 Answers8

9

Martin Fowler would favour the early return, and calls the idea a Guard Clause.

Personally, I don't like it in Java, as I prefer one return per method. However this is subjective and I may be in the minority.

I've blogged about this for and against.

Michael Easter
  • 23,733
  • 7
  • 76
  • 107
8

That is not a return, it's an exception. The code is perfectly ok tho.

Even if you'd replace that throw with a "return something", it would still be ok.

user229321
  • 304
  • 1
  • 3
  • 7
  • Whoops, so it is. I originally placed a simple return until I was told it was a bad practise to do so, especially since it indicated the absence of a ServletContext in this case. – James P. Dec 11 '09 at 15:10
  • 2
    It's not bad practice, but if that is an exceptional case, you should throw, like you used to in the original code. Avoid handling critical errors, if that object shouldn't be null, just let the program crash and when it will crash, debug. – user229321 Dec 11 '09 at 15:32
7

I think it comes down to readability. The code should function the same either way.

I use stuff like this all the time

Function Blah() As Boolean
  If expr Then
     Return False
  End If
  Do Other work...

  Return result

End Function
hometoast
  • 11,522
  • 5
  • 41
  • 58
  • 1
    The readability argument has convinced me to use this by default. Thanks for your giving your point of view. – James P. Dec 11 '09 at 15:25
4

For error conditions, generally it's best to throw an exception - exception handling was invented to get rid of the manual return code style error checking in C that comprises about 30% of a C program.

However, early returns are fine - they are far more readable than adding an extra scope with curly braces.

if (!_cache.has_key(key))
    return null;

return _cache[key]

Is better than:

if (_cache_has_key(key))
{
    return _cache[key]
}
else
    return null;

And it only gets more obvious the more early returns that you add, 5 early returns beats the hell out of 5 nested if statements.

Note that I didn't return null on an error condition, it's expected that often the key won't be in the cache - but it still means the caller has to write code to check the result. In .NET there's a better pattern of returning a boolean, and setting the result via an out parameter. The methods beginning with Try usually follow this pattern:

Foo foo;
if (!TryGetCachedFoo("myfoo", foo))
{
    foo = new Foo(...);
    AddToCache("myfoo", foo);
}

// do something with foo
Eloff
  • 20,828
  • 17
  • 83
  • 112
3

As long as you're using them for conditional escapes as the first thing in the routine. I think the fact that they are obvious in that location, and avoid at least one level of indentation outweighs the negative of having a multiple returns.

Vincent
  • 421
  • 2
  • 4
3

In the example you give, I'd favor throwing an exception because a null ServletContext is usually a sign that something has gone wrong. However, there are times when checking whether a parameter is null and returning immediately from the method is both useful and valid.

For instance, if you are gathering contact information about a user and the user has the option of providing a phone number. In that case, you may have a method that validates that the phone number contains all numbers, has the correct number of digits, etc, but which would immediately return if the phone number was empty or null.

public void validatePhone(String phoneNumber) throws ValidationException {

if (phoneNumber == null || phoneNumber.equals("")) {
    return;
}
//do validation stuff, throwing exception if not valid

John Kinzie
  • 361
  • 2
  • 8
  • Why throw an exception only if it's not valid, and don't throw it when it is `null` or empty? – True Soft Dec 11 '09 at 17:08
  • 1
    @True There's no exception if it is null or empty because in this scenario the user has the option of either providing or not providing the phone number. Null or empty is valid. – John Kinzie Dec 11 '09 at 17:53
2

In your example, there is no return after the if statement; you are throwing an exception. (edit: I see you have changed the code since I posted this answer).

There are purists who think that you should have only one return statement in a method (at the end of the method). There's some merit to that idea - it makes the code more clear, it makes it easier to see what can be returned for the method, and especially when you need to cleanup resources (especially in a language without garbage collection; or in Java where you need to close for example an InputStream) it's more clear and easier if you have just one return at the bottom, and do the cleanup code just before the return.

I would not have any objection against the code in your example, however.

Jesper
  • 202,709
  • 46
  • 318
  • 350
1

I have a few (subjective, or not) remarks:

  • I always use accolades with a if even the block contains only one line
  • I don't like to have many return on one method
  • I don't think that this null check is necessary. If getServletContext() returns null, then you have a much bigger problem with your webapp that should definitely be fixed. In that case, having a NullPointerException later in the code is an exceptional error so I wouldn't bother handling it.
Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124