避免使用try-catch语句的充分理由

时间:2011-03-26 03:02:44

标签: java exception-handling try-catch

示例#1:

try { fileChooser.setSelectedFile(new File(filename)); }
catch (NullPointerException e) { /* do nothing */ }

示例#2:

if (filename != null)
    fileChooser.setSelectedFile(new File(filename));

由于性能或稳定性(或任何其他原因),#1本质上是不好的,还是只是有点不同?这不是一个很好的例子,因为#1优于#2没有优势,但在不同情况下可能会有(例如提高可读性,减少代码行数等)。


编辑:协商一致似乎是#1是禁忌。最受欢迎的原因:开销

此外, @Raph Levien 有很好的见解:

避免#1的一个原因是它会使您使用异常断点的能力中毒。正常运行的代码永远不会故意触发空指针异常。因此,将调试器设置为每次发生时都停止是有意义的。在#1的情况下,您可能会例行地获得此类异常。除了其他充分的理由之外,还有潜在的性能影响。

此外,See Link更深入。

7 个答案:

答案 0 :(得分:8)

绝对是#2是更好的选择。不应将异常处理用作程序控制流中的构造。应该使用例外来处理不受程序员控制的情况。在此示例中,您可以检查fileChooser是否为null,以便您可以控制。

答案 1 :(得分:5)

异常会带来一定的开销。如果可以避免它们,在这种情况下,只需检查一个null,那将是首选。

正如其他人所说,使用Exceptions进行流量控制通常也是不好的做法。有关错误原因的详细说明,请查看this.

以下是答案的简短说明:

  

异常基本上是非本地goto语句,具有后者的所有后果。使用流控制的异常违反了最不惊讶的原则,使程序难以阅读(记住程序首先是为程序员编写的)。

答案 2 :(得分:5)

  • 不要使用Exception来控制逻辑流程。
  • 永远不要吞下异常。 #1违反了它 - 你永远不会知道NPE是来自fileChooser==null还是fileName==null

答案 3 :(得分:4)

如果程序在逻辑上允许空值,请对其进行测试。否则使用例外。例外是为了处理异常情况(惊喜!),不应该用于程序逻辑。

答案 4 :(得分:3)

避免#1的一个原因是它会使您使用异常断点的能力中毒。正常运行的代码永远不会故意触发空指针异常。因此,将调试器设置为每次发生时都停止是有意义的。在#1的情况下,您可能会例行地获得此类异常。除了其他充分的理由之外,还有潜在的性能影响。

答案 5 :(得分:2)

我选择#3选项 - 如果filename作为函数参数传递,请在注释中注明不允许使用空文件名。然后只需假设文件名永远不为空:

fileChooser.setSelectedFile(new File(filename));

如果某个白痴(或你,< 3)忽略了你的评论并且''确实''传递了一个null,他将得到一个NullPointerException并且必须解决问题。

在客户端代码中,始终通过初始化或将fileName默认为空字符串来确保没有传递空值。

我一直在避免使用和接受空值一段时间,而且我的代码更清晰,因为它已经没有那么多的空检查了。唯一仍然存在的空检查是我调用可能返回null的第三方代码的那些。

(咆哮:当然,我必须反编译所说的第三方代码并确定我自己,考虑到文档不存在或者没有记录它可能返回null)

答案 6 :(得分:2)

在以下情况下,您的两个示例在语义上不相同:

  • fileChoosernull
  • setSelectedFile抛出一个NullPointerException(授予,这种特殊方法不会发生这种情况,但一般情况下,setter很可能将东西存储在其他对象中,如果该另一个对象的引用未初始化)
  • new File()因“NullPointerException filename
  • 以外的其他原因而引发null

可能/* do nothing */仅适用于filename为空的情况,但现在也隐藏其他情况,而良好的异常处理会允许这些异常冒泡调用堆栈,警告你要找到一个你很难找到的错误的存在和原因。

我觉得这比性能更令人信服,因为浪费的程序员时间比浪费的cpu时间贵得多。