return in try block vs return after the block

I have a try statement in a small static method, is there a best practice as to where I should return from?

try { mightThrow(); return true;
} catch (Exception e) { return false;
}

or after,

try { mightThrow();
} catch (Exception e) { return false;
}
return true;

Functionally, these should preform identically, is there actually a bytecode difference? Performance wise, are they the exact same?

Or is one just preferred over the other? Which and why?

1

3 Answers

I haven't heard of an actual best practice in this matter, but you often see that when methods use premature returns, the returns true case is at the bottom, e.g.

public bool canReadFile(path) { if (!fileExists(path)) return false; if (!fileIsReadable(file)) return false; ... return true;
}

Because of that, I'd suggest you follow this practice for try/catch blocks. It also makes it quicker to see what the "expected" return value is.

In regards to the bytecode, then yes, there is indeed a difference. I made a quick sample program

class TryBlock { public static void main(String[] args) { a(); b(); } public static boolean a() { try { System.out.println("A"); return true; } catch (Exception e) { return false; } } public static boolean b() { try { System.out.println("B"); } catch (Exception e) { return false; } return true; }
}

Then compiled it and inspected the bytecode

$ javac TryBlock.java; javap -c TryBlock
Compiled from "TryBlock.java"
class TryBlock { TryBlock(); Code: 0: aload_0 // Method java/lang/Object."<init>":()V 1: invokespecial #1 4: return public static void main(java.lang.String[]); Code: // Method a:()Z 0: invokestatic #2 3: pop // Method b:()Z 4: invokestatic #3 7: pop 8: return public static boolean a(); Code: // Field java/lang/System.out:Ljava/io/PrintStream; 0: getstatic #4 // String A 3: ldc #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 5: invokevirtual #6 8: iconst_1 9: ireturn 10: astore_0 11: iconst_0 12: ireturn Exception table: from to target type 0 9 10 Class java/lang/Exception public static boolean b(); Code: // Field java/lang/System.out:Ljava/io/PrintStream; 0: getstatic #4 // String B 3: ldc #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 5: invokevirtual #6 8: goto 14 11: astore_0 12: iconst_0 13: ireturn 14: iconst_1 15: ireturn Exception table: from to target type 0 8 11 Class java/lang/Exception
}

So is there a performance difference? While I haven't tested, my bet is there won't be anything noticeable. On top of that, this will hardly be the bottleneck of your application.

2

To me this is more a semantics and readability issue.

If your return true is at the end of the segment outside of the try/catch block, it means this function is supposed to return true value unless anything bad happened in between which interrupts the normal flow.

Instead if the return true is at the end of the try block, it means the function should only return true if all the attempts in the try block succeeded.

This difference in byte code is more or less neglectable; and I agree with @kba this is more a style issue. Many return statement at different places inside deeply embedded if blocks would usually be confusing; so it's a good practice to make your code less complex. I.e.

  1. Use flat blocks than deep embed where possible
  2. Carry less state to another code segment and/or an inner if, for or try block
  3. Use less state and flow controlling variable
  4. Use less statement like return or go because they are more or less a compulsory change of the logic flow.

Hope that helps.

Return is always set false for any type of exception. This may not be the case you will be expecting. May be some of the unexpected exceptions would cause a false value to be returned. So not a good standard way of returning in catch

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like