我在一个小的静态方法中有一个try语句,有关于我应该从哪里返回的最佳实践吗?
try {
mightThrow();
return true;
} catch (Exception e) {
return false;
}
或之后,
try {
mightThrow();
} catch (Exception e) {
return false;
}
return true;
从功能上讲,这些应该预先形成相同的,实际上是否存在字节码差异?性能方面,它们是完全相同吗?
或者一个人比另一个更受欢迎?哪个以及为什么?
答案 0 :(得分:8)
我没有听说过这个问题的实际最佳做法,但是你经常看到当方法使用过早返回时,返回true
的情况就在底部,例如。
public bool canReadFile(path) {
if (!fileExists(path))
return false;
if (!fileIsReadable(file))
return false;
...
return true;
}
因此,我建议你按照这种方法进行try / catch块。它还可以更快地查看“预期”返回值是什么。
关于字节码,那么是的,确实存在差异。我做了一个快速的示例程序
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;
}
}
然后编译并检查字节码
$ 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
}
那么性能差异是什么?虽然我没有测试,但我的赌注是没有任何明显的东西。最重要的是,这几乎不是您申请的瓶颈。
答案 1 :(得分:2)
对我而言,这更像是语义和可读性问题。
如果你的return true
位于try/catch
块之外的段的末尾,则意味着该函数应该返回true值,除非在它们之间发生中断正常流的任何不良情况。
相反,如果return true
位于try
块的末尾,则表示如果try块中的所有尝试都成功,则该函数应该只返回true。
这种字节码的差异或多或少可以忽略不计;我同意@kba这更像是一个风格问题。在深度嵌入的return
块内的不同位置的许多if
语句通常会令人困惑;因此,使代码不那么复杂是一种很好的做法。即。
if
,for
或try
块return
或go
,因为它们或多或少是逻辑流程的强制更改。希望有所帮助。
答案 2 :(得分:0)
对于任何类型的异常,返回始终设置为false。这可能不是您期望的情况。可能是某些意外的异常会导致返回false值。所以不是一个很好的标准回归方式