Return to try block vs return after block

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

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

or after

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

Functionally, they should blank the same way, is there a bytecode? Performance wise, are they accurate ?

Or is one of them preferable to the other? What and why?

+4
source share
3 answers

I have not heard about real best practices in this matter, but you often see that when methods use premature returns, the case of returning true is at the bottom, for example.

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

Because of this, I suggest you follow this practice for try / catch blocks. It also allows you to quickly find out what the "expected" return value means.

As for the bytecode, yes, there really is 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 checked 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 } 

Is there a difference in performance? Until I tested, my bet will not be noticeable. Also, this is unlikely to be the bottleneck of your application.

+8
source

For me, it is rather a problem of semantics and readability.

If your return true is at the end of the segment outside the try/catch , this means that this function should return a true value, unless something bad happens between them that interrupts the normal flow.

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

This difference in byte code is more or less not taken into account; and I agree with @kba, this is more a style issue. Many return in different places inside deeply embedded if blocks are usually confusing; so it's good practice to make your code less complicated. I.e.

  • Use flat blocks than deep implantation where possible.
  • Transfer the smaller state to a different code segment and / or an internal if , for or try block
  • Use the smaller state and flow control variable.
  • Use a smaller expression, such as return or go , because it is a more or less forced change to the logical stream.

Hope this helps.

+2
source

Returns are always set to false for any type of exception. This may not be what you expect. Perhaps some of the unexpected exceptions will return a false value. So not a good standard way to return to catch

0
source

All Articles