Java 什么时候可以捕获 RuntimeException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1982533/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When is it OK to catch a RuntimeException
提问by VDev
On a recent project I recommended catching a RuntimeException within a test harness code and logging it. The code processes a series of inputs from a database, and I do not want the test to stop due to failure of any one input (Null values, Illegal arguments, etc.). Needless to say, my suggestion triggered a passionate discussion.
在最近的一个项目中,我建议在测试工具代码中捕获 RuntimeException 并记录它。该代码处理来自数据库的一系列输入,我不希望测试因任何一个输入(空值、非法参数等)失败而停止。不用说,我的建议引发了热烈的讨论。
Is catching any kind of RuntimeException acceptable? If yes, what are other scenarios where it is OK to catch RuntimeExceptions?
是否可以接受任何类型的 RuntimeException?如果是,可以捕获 RuntimeExceptions 的其他场景是什么?
采纳答案by kdgregory
You catch RuntimeException
for the same reason that you catch any exception: You plan to do something with it. Perhaps you can correct whatever caused the exception. Perhaps you simply want to re-throw with a different exception type.
您捕获RuntimeException
任何异常的原因与捕获任何异常的原因相同:您计划用它做某事。也许您可以纠正导致异常的任何内容。也许您只是想用不同的异常类型重新抛出。
Catching and ignoringany exception, however, is extremely bad practice.
然而,捕捉和忽略任何异常是非常糟糕的做法。
回答by Topher Fangio
Personally, I've always been told that you want to catch allRuntimeExceptions; however, you also want to do something aboutthe exception, such as running a failsafe or possibly just informing the user that an error occurred.
就我个人而言,我一直被告知要捕获所有RuntimeExceptions;但是,你也想要做的事有关的例外,如运行故障安全或者可能只是告知出现了错误的用户。
The last Java project that I worked on had a similar approach, at the very least, we would log the exception so that if a user called complaining about a bug, we could find out exactly what happened and see where the error occurred.
我参与的最后一个 Java 项目也有类似的方法,至少,我们会记录异常,以便如果用户打电话抱怨错误,我们可以确切地找出发生了什么并查看错误发生的位置。
Edit 1:As kdgregory said, catching and ignoring are two different things, generally, people are opposed to the latter :-)
编辑 1:正如 kdgregory 所说,捕捉和忽略是两件不同的事情,一般来说,人们反对后者:-)
回答by TofuBeer
RuntimeException is intended to be used for programmer errors. As such it should never be caught. There are a few cases where it should be:
RuntimeException 旨在用于程序员错误。因此,它永远不应该被抓住。有几种情况应该是:
you are calling code that comes from a 3rd party where you do not have control over when they throw exception. I would argue that you should do this on a case by case basis and wrap the usage of the 3rd party code within your own classes so you can pass back non-runtime exceptions.
your program cannot crash and leave a stack trace for the user to see. In this case it should go around main and around any threads and event handling code. The program should probably exit when such exception occurs as well.
您正在调用来自第三方的代码,您无法控制他们何时抛出异常。我认为您应该根据具体情况执行此操作,并将第 3 方代码的使用包装在您自己的类中,以便您可以传回非运行时异常。
您的程序不会崩溃并留下堆栈跟踪供用户查看。在这种情况下,它应该围绕 main 和任何线程和事件处理代码。当发生此类异常时,程序可能也应该退出。
In your specific case I would have to question why you are having RuntimeExceptions occur in the tests - you should be fixing them instead of working around them.
在您的特定情况下,我不得不质疑为什么您在测试中出现 RuntimeExceptions - 您应该修复它们而不是解决它们。
So you should guarantee that your code only throws RuntimeExceptions when you want to have the program exit. You should only catch RuntimeExceptions when you want to log it and exit. That is what is in line with the intent of RuntimeExceptions.
所以你应该保证你的代码只在你想让程序退出时抛出 RuntimeExceptions。您应该只在想要记录并退出时捕获 RuntimeExceptions。这符合 RuntimeExceptions 的意图。
You can look at this discussionfor some other reasons that people give... I personally haven't found a compelling reason in the answers though.
回答by Martin York
In my code 99% of my exceptions are derived from runtime_exception.
在我的代码中,99% 的异常都来自 runtime_exception。
The reasons I catch exceptions are:
我捕获异常的原因是:
- Catch Log and Fix problem.
- Catch Log and Generate a more specific exception and throw
- Catch Log and rethrow.
- Catch Log and Kill operation (discard exception)
- User/request initiated action fails.
An HTTP request handler for example. I would rather the requested operation die rather than bring the Service down. (Though preferably the handler has enough sense to return a 500 error code.) - Test case passed/failed with an exception.
- All exceptions not in the main thread.
Allowing exceptions to escape a thread is usually badly documented but usually causes program termination (without stack unwinding).
- User/request initiated action fails.
- 捕获日志并修复问题。
- 捕获日志并生成更具体的异常并抛出
- 捕获 Log 并重新抛出。
- Catch Log 和 Kill 操作(丢弃异常)
- 用户/请求启动的操作失败。
例如 HTTP 请求处理程序。我宁愿请求的操作死亡,也不愿关闭服务。(尽管最好处理程序有足够的意义来返回 500 错误代码。) - 测试用例通过/失败,但出现异常。
- 所有不在主线程中的异常。
允许异常逃逸线程通常被错误地记录,但通常会导致程序终止(没有堆栈展开)。
- 用户/请求启动的操作失败。
回答by raoulsson
Unless you can correct a RuntimeException, you don't want to catch it...
除非您可以更正 RuntimeException,否则您不想捕获它...
...only true from a developers point of view....
...仅从开发人员的角度来看才是正确的....
you have to catch all exceptions before they reach up to the UI and make your user sad. This means on the "highest level" you want to catch anything that happend further down. Then you can let the user know there was a problem and at the same time take measures to inform the developers, like sending out alarm mails or whatever...
您必须在异常到达 UI并让您的用户感到难过之前捕获所有异常。这意味着在“最高级别”上,您希望捕捉更远的地方发生的任何事情。然后你可以让用户知道有问题,同时采取措施通知开发人员,比如发送警报邮件或其他什么......
It is basically considered a data/programming error that could not be forseen, thus you want to improve future releases of the software while at the same time take the user by the hand and move on in a controlled manner...
它基本上被认为是无法预见的数据/编程错误,因此您希望改进软件的未来版本,同时让用户掌握并以受控方式继续前进......
回答by fastcodejava
You catch RuntimeException
when you want to process it. Maybe you want to rethrow it as a different exception or log it to a file or database, or you want to turn on some exception flag in the return type, etc.
RuntimeException
当你想处理它时,你会抓住它。也许您想将其作为不同的异常重新抛出或将其记录到文件或数据库中,或者您想在返回类型中打开某些异常标志等。
回答by Kevin Reid
You catch RuntimeExceptions (in any language: unexpected exceptions/“all” exceptions) when your program is doing multiple subtasks and it makes sense to complete every one you can rather than stopping on the first unexpected situation. A test suite is a fine situation to do this — you want to know which of allthe tests failed, not just the first test. The key characteristic is that each test is independent of all the others — it doesn't matter whether a previous test doesn't run because the order is not significant anyway.
当您的程序正在执行多个子任务时,您会捕获 RuntimeExceptions(在任何语言中:意外异常/“所有”异常),并且您可以完成每个子任务而不是在第一个意外情况下停止是有意义的。测试套件是一个很好的情况——你想知道所有测试中的哪一个失败了,而不仅仅是第一个测试。关键特征是每个测试都独立于所有其他测试——之前的测试是否不运行并不重要,因为顺序并不重要。
Another common situation is a server; you don't want to shut down just because one request was malformed in a way you didn't expect. (Unless it's really, really important to minimize the chances of inconsistent state.)
另一种常见情况是服务器;您不想仅仅因为一个请求以您没想到的方式格式错误而关闭。(除非将状态不一致的可能性降到最低真的非常重要。)
In any of these situations, the appropriate thing to do is log/report the exception and continue with the remaining tasks.
在任何这些情况下,正确的做法是记录/报告异常并继续执行剩余的任务。
One could vaguely generalize to any exception: it is “appropriate to catch” an exception if and only if there is something sensible to do aftercatching it: how your program should continue.
人们可以隐约推广到任何异常:它是“适当的,以捕获”异常当且仅当有一些明智的做后捕获它:你的程序应该如何继续。
回答by Tim Williscroft
Years ago, we wrote a control system framework and the Agent objects caught runtime exceptions, logged them if they could and continued.
多年前,我们编写了一个控制系统框架,代理对象捕获了运行时异常,如果可以,则记录它们并继续。
Yes we caught Runtimeexceptions including OutOfMemory in our framework code( and forced a GC, and it's surprising how well that kept even quite leaky code running.) We had code that was doing very mathematical things involving the real world; and from time to time a Not-A-Number would get in due to tiny rounding errors and it coped okay with that too.
是的,我们在框架代码中捕获了包括 OutOfMemory 在内的运行时异常(并强制执行了 GC,令人惊讶的是,即使是非常泄漏的代码也能保持运行良好。)并且有时会由于微小的舍入错误而出现非数字,并且它也可以很好地应对。
So in framework / "must not exit" code I think it can be justifiable. And when it works it's pretty cool.
所以在框架/“不得退出”代码中,我认为这是有道理的。当它起作用时,它非常酷。
The code was pretty solid, but it ran hardware, and hardware tends to give screwy answers sometimes.
代码非常可靠,但它运行硬件,有时硬件往往会给出奇怪的答案。
It was designed to run without human intervention for months at a time. It worked extremely well in our tests.
它的设计目的是在没有人为干预的情况下一次运行数月。它在我们的测试中非常有效。
As part of the error recovery code, it could resort to rebooting the entire building using the UPS's ability to turn off in N minutes and turn on in M minutes.
作为错误恢复代码的一部分,它可以使用 UPS 在 N 分钟内关闭并在 M 分钟内打开的能力重新启动整个建筑物。
Sometimes hardware faults need to power cycled :)
有时硬件故障需要重启:)
If I remember, the last resort after an unsuccessful power cycle was it sending an email to it's owners, saying "I tried to fix myself and I can't; the problem is in subsystem XYZ", and included a link to raise a support call back to us.
如果我记得,在重新启动失败后的最后一招是向其所有者发送电子邮件,说“我试图修复自己,但我不能;问题出在子系统 XYZ”中,并包含一个链接以寻求支持回电给我们。
Sadly the project got canned before it could become self aware :)>
可悲的是,该项目在自我意识到之前就被淘汰了:)>
回答by sunya
We all know that checked exceptions and RuntimeExceptions
are the two categories of exceptions. It is always suggested that we handle (either try-catch or throw) the checked exceptions because they are the programming conditions where unfortunately programmer can not to do anything on its own;
Like FileNotFoundException
it is not the programmer who puts files on user's drive if program is actually trying to read the file 1.txt
which is supposed to be there on f:\
of user with the statements:
我们都知道检查异常和异常RuntimeExceptions
是两类。总是建议我们处理(try-catch 或 throw)已检查的异常,因为它们是编程条件,不幸的是程序员不能自己做任何事情;就像FileNotFoundException
它不是谁把文件中的用户的硬盘上,如果程序实际上是试图读取该文件的程序员1.txt
这应该是那里f:\
的与用户的语句:
File f11 = new File("f:\1.txt");
FileInputStream fos = new FileInputStream(f11);
If the file is found it's all ok, but what happens in the other case if the file is not found is that, program crashes down with 0 error from the user. In this scenario programmer did not do anything wrong. This could be a checked exception which must be caught for the program to continue running.
如果找到该文件,则一切正常,但在另一种情况下,如果找不到该文件,则程序会因用户的 0 错误而崩溃。在这种情况下,程序员没有做错任何事情。这可能是一个已检查的异常,必须捕获它才能让程序继续运行。
Let me also explain the second scenario with which the concept of RuntimeException
will be clear. Consider following code:
让我也解释一下概念RuntimeException
会很清楚的第二种情况。考虑以下代码:
int a = {1,2,3,4,5};
System.out.println(a[9]);
This is poor coding which generates the ArrayIndexOutOfBoundsException
. Which is an example of RuntimeException
. So programmer should not actually handle the exception, let it crash the program, and later fix the logic.
这是一种糟糕的编码,会生成ArrayIndexOutOfBoundsException
. 这是RuntimeException
. 所以程序员不应该实际处理异常,让它崩溃程序,然后修复逻辑。
回答by VdeX
If a client can reasonably be expected to recover from an exception, make it a checked exception.
如果可以合理地期望客户端从异常中恢复,请将其设置为已检查的异常。
If a client cannot do anything to recover from the exception, make it an unchecked exception.
如果客户端无法从异常中恢复,请将其设为未经检查的异常。
Here's the bottom line guideline.
这是底线指南。
From Java Docs. Please read this Unchecked Exceptions — The Controversy
来自 Java文档。请阅读未经检查的异常 — 争议