Java – return try block in block vs return block
I have a try statement in a small static method. Is there a best practice for where I should return?
try { mightThrow(); return true; } catch (Exception e) { return false; }
Or later,
try { mightThrow(); } catch (Exception e) { return false; } return true;
Functionally, these should be the same in advance. Is there actually a bytecode difference? Are they identical in terms of performance?
Or does one take precedence over the other? Which and why?
Solution
I haven't heard of practical best practices for this problem, but you often see that when a method uses premature return, the return of true is at the bottom, for example
public bool canReadFile(path) { if (!fileExists(path)) return false; if (!fileIsReadable(file)) return false; ... return true; }
Therefore, I suggest you follow this approach to try / catch blocks It can also see more quickly what the "expected" return value is
With regard to bytecode, then yes, there are differences I made a quick example 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 compile it and check 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 what are the performance differences? Although I didn't test, my bet was nothing obvious Most importantly, this is hardly the bottleneck of your application