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
