Java 为什么捕获 RuntimeException 不被认为是一种好的编程习惯?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24344511/
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
Why is catching a RuntimeException not considered a good programming practice?
提问by Sumit Pal Singh
Why is catching a RuntimeException
using catch(Throwable exc) {}
not considered a good programming practice? What is the right way to handle RuntimeExceptions?
为什么捕获RuntimeException
usingcatch(Throwable exc) {}
不被认为是一种好的编程习惯?处理 RuntimeExceptions 的正确方法是什么?
Also, why does catch(Exception exc) {}
not catch RuntimeException
? How is this behavior implemented?
还有,为什么不catch(Exception exc) {}
赶上RuntimeException
?这种行为是如何实现的?
采纳答案by Jon Skeet
Usually, a RuntimeException
indicates a programming error (in which case you can't "handle" it, because if you knew to expect it you'd have avoided the error).
通常,aRuntimeException
表示编程错误(在这种情况下,您无法“处理”它,因为如果您知道会发生这种情况,您就可以避免该错误)。
Catching any of these general exceptions (including Throwable
) is a bad idea because it means you're claiming that you understand every situation which can go wrong, and you can continue on despite that. It's sometimes appropriate to catch Exception
(but not usually Throwable
) at the top level of the stack, e.g. in a web server - because usually whatever's gone wrong with a singlerequest, you normally want to keep the server up and responding to further requests. I don't normally catch Throwable
, as that includes Error
subclasses which are normally used to indicate truly catastrophic errors which would usually be best "handled" by terminating the process.
捕获这些一般异常(包括Throwable
)中的任何一个都是一个坏主意,因为这意味着您声称您了解可能出错的每种情况,尽管如此,您仍可以继续。有时在堆栈的顶层捕获Exception
(但通常不是Throwable
)是合适的,例如在 Web 服务器中 - 因为通常无论单个请求出现什么问题,您通常都希望保持服务器正常运行并响应进一步的请求。我通常不会 catch Throwable
,因为它包括Error
通常用于指示真正灾难性错误的子类,这些错误通常最好通过终止进程来“处理”。
Fundamentally, when there's an error you need to be very cautious about continuing with a particular task - you need to really have a pretty good idea about what the error means, as otherwise you could go ahead with a mistaken assumption about the state of the world, and make things worse. In mostcases (not all), simply giving up on a request is better than trying to carry on regardless of a mysterious failure. (It does very much depend on context though - you might not care what went wrong when trying to fetch one piece of secondary information, for example.)
从根本上说,当出现错误时,您需要非常谨慎地继续执行特定任务 - 您需要真正了解错误的含义,否则您可能会继续错误地假设世界状况,让事情变得更糟。在大多数情况下(不是全部),简单地放弃请求比不顾神秘的失败尝试继续进行要好。(不过,它在很大程度上取决于上下文——例如,在尝试获取一条次要信息时,您可能不关心出了什么问题。)
As for catching Exception
not catching RuntimeException
- that's simply not true. The only odd thing about RuntimeException
is that it (and subclasses) are unchecked exceptions, whereas Exception
and all other subclasses of Exception
are checked.
至于抓Exception
不抓RuntimeException
——那根本就不是真的。唯一奇怪的RuntimeException
是它(和子类)是未经检查的异常,而Exception
和 所有其他子类Exception
都经过检查。
回答by Subhrajyoti Majumder
Throwable is super class of all Exception
checked and unchecked(RuntimeException
) and error.
Throwable 是所有Exception
checked 和unchecked( RuntimeException
) 和error 的超类。
java.lang.Object
java.lang.Throwable
java.lang.Exception
java.lang.RuntimeException
java.lang.Error
Ideally catching error is not a good practice.
理想情况下,捕获错误不是一个好习惯。
And as RuntimeException
extends Exception
so it catches all RuntimeExcption
's.
并且 as RuntimeException
extendsException
所以它捕获了所有RuntimeExcption
的。
回答by Makoto
It boils down to the different types of exceptions there actually are.
它归结为实际存在的不同类型的异常。
Checked exceptions (that is, exception classes that extend Exception
) are typically errors you can recover from.
检查的异常(即扩展的异常类Exception
)通常是可以从中恢复的错误。
Unchecked exceptions (that is, exception classes that explicitly extend RuntimeException
) are those that indicate an error in either expected behavior or program state. You wouldn't get a NullPointerException
if the state of an object wasn't null
when you dereferenced it, of course.
未经检查的异常(即显式扩展的异常类RuntimeException
)是那些指示预期行为或程序状态错误的异常。当然,NullPointerException
如果对象的状态不是null
在您取消引用它时,您就不会得到 a 。
Blanket-catching everything- either Exception
or Throwable
, which is farworse - is not a good practice because you're assuming that you can recover from anyexceptional behavior. There are some cases in which you shouldn't, or realistically can't (i.e. OutOfMemoryError
for catch(Throwable t)
). Further, catching runtime exceptions indicates a code smell; it means that you're covering up a coding error.
毛毯醒目的一切-无论是Exception
或Throwable
,这是远远更糟-是不是因为你假设你可以从恢复良好做法的任何异常行为。在某些情况下,您不应该或实际上不能(即OutOfMemoryError
对于catch(Throwable t)
)。此外,捕获运行时异常表明代码有异味;这意味着您正在掩盖编码错误。
Be explicitabout what it is you're catching.
明确说明你在捕捉什么。
Aside: Yes, catch Exception
will also catch RuntimeException
, since Exception
is a superclass of RuntimeException
. Just the same, Throwable
will catch Exception
and Error
, which is why it's worse to write catch(Throwable t)
.
旁白:是的,catch Exception
也会 catch RuntimeException
,因为Exception
是 的超类RuntimeException
。一样,Throwable
会捕捉Exception
和Error
,这就是为什么写更糟糕的原因catch(Throwable t)
。