何时可以捕获RuntimeException

VDe*_*Dev 65 java exception-handling

在最近的一个项目中,我建议在测试工具代码中捕获RuntimeException并记录它.代码处理来自数据库的一系列输入,我不希望测试因任何一个输入失败而停止(Null值,Illegal arguments等).不用说,我的建议引发了激烈的讨论.

捕获任何类型的RuntimeException都可以接受吗?如果是,那么可以捕获RuntimeExceptions的其他方案是什么?

kdg*_*ory 94

你捕获RuntimeException的原因与捕获任何异常的原因相同:你打算用它做点什么.也许你可以纠正导致异常的任何事情.也许你只想用不同的异常类型重新抛出.

但是,捕捉并忽略任何异常都是非常糟糕的做法.

  • 或者抓住日志并重新抛出. (21认同)
  • 呵呵,我认为这更多是让“所有”异常成为运行时异常的原因。有很多程序员会捕获并忽略已检查的异常,只是为了让它们消失。 (3认同)
  • 完全有道理,应该回到基础.很多时候,模式变得如此刻板,以至于开发人员倾向于把它们当作教条.我一直被告知RuntimeExceptions是a)编程错误的结果b)无法恢复的灾难性故障.在(a)的情况下,您希望确保在产品上线之前一切都已修复,并且"永远不会"发生.对于情况(b),用户应该看到更加消毒的消息对于捕获和处理是完全合理的.现在我想知道为什么我们需要RuntimeExceptions,也许是另一个讨论的主题;-) (2认同)

rao*_*son 33

除非你能纠正RuntimeException,否则你不想抓住它......

......从开发人员的角度来看......

你必须在它们到达用户界面之前捕获所有异常并让你的用户感到悲伤.这意味着在"最高级别",您希望捕捉到进一步发生的任何事情.然后,您可以让用户知道存在问题,同时采取措施通知开发人员,例如发送警报邮件或其他任何内容......

它基本上被认为是一个无法预测的数据/编程错误,因此您希望改进软件的未来版本,同时让用户亲自操作并以受控方式继续...


Tof*_*eer 15

RuntimeException旨在用于程序员错误.因此,它永远不应该被抓住.有几种情况应该是:

  1. 您正在调用来自第三方的代码,在这些代码中,您无法控制何时抛出异常.我认为你应该根据具体情况这样做,并将第三方代码的使用包装在你自己的类中,这样你就可以传回非运行时异常.

  2. 您的程序不会崩溃并留下堆栈跟踪供用户查看.在这种情况下,它应该围绕主要和围绕任何线程和事件处理代码.当发生此类异常时,该程序可能应该退出.

在您的具体情况下,我将不得不质疑为什么您在测试中出现RuntimeExceptions - 您应该修复它们而不是解决它们.

因此,当您希望程序退出时,您应该保证您的代码只会抛出RuntimeExceptions.只有在想要记录并退出时才应捕获RuntimeExceptions.这符合RuntimeExceptions的意图.

你可以看看这个讨论是出于人们给出的其他一些原因......我个人在答案中没有找到令人信服的理由.


Mar*_*ork 7

在我的代码中,99%的异常都是从runtime_exception派生的.

我捕获异常的原因是:

  • 捕获日志和修复问题.
  • 捕获日志并生成更具体的异常并抛出
  • 抓住日志并重新抛出.
  • 捕获日志和杀死操作(丢弃例外)
    • 用户/请求启动的操作失败.
      例如,HTTP请求处理程序.我宁愿所请求的操作死亡而不是降低服务.(尽管处理程序最好有足够的意义来返回500错误代码.)
    • 测试用例通过/失败,但有异常.
    • 所有异常都不在主线程中.
      允许异常转义线程通常记录很差,但通常会导致程序终止(没有堆栈展开).


Tim*_*oft 7

几年前,我们编写了一个控制系统框架,Agent对象捕获了运行时异常,如果可以继续记录它们.

是的,我们在框架代码中捕获了包括OutOfMemory在内的运行时异常(并强制使用GC,并且令人惊讶的是,即使是非常漏洞的代码运行也是如此.)我们的代码执行涉及现实世界的非常数学化的东西; 由于微小的舍入误差,Not-A-Number会不时地进入,并且它也可以应对.

所以在框架/"必须不退出"代码中我认为它是合理的.当它工作时它非常酷.

代码非常可靠,但它运行硬件,硬件往往会给出棘手的答案.

它的设计目的是在没有人为干预的情况下运行数月.它在我们的测试中表现得非常好.

作为错误恢复代码的一部分,它可以使用UPS在N分钟内关闭并在M分钟内打开来重新启动整个建筑物.

有时硬件故障需要重启电源:)

如果我记得,电源循环失败后的最后一招是它向其所有者发送电子邮件,说"我试图修复自己,我不能;问题出在子系统XYZ",并包含一个提供支持的链接给我们回电话.

可悲的是,这个项目在它变得自我意识之前得到了罐头:))

  • OutOfMemoryError是一个错误而不是例外 (4认同)

Top*_*gio 5

就我个人而言,我一直被告知要捕获所有RuntimeExceptions;但是,你也想要做的事有关的例外,如运行故障安全或者可能只是告知出现了错误的用户。

我参与的最后一个 Java 项目也有类似的方法,至少,我们会记录异常,以便如果用户打电话抱怨错误,我们可以确切地找出发生了什么并查看错误发生的位置。

编辑 1:正如 kdgregory 所说,捕捉和忽略是两件不同的事情,一般来说,人们反对后者:-)